如何将 CString 转换为 long? VC++

How to convert CString to long? VC++

如何在 VC++ 中将 CString 转换为 long。我用过 atol 但它抛出错误。

long ldata = atol(str);

错误,没有从 CStringconst char* 的合适转换。

来自 https://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

"To use a CString object as a C-style string, cast the object to LPCTSTR."

所以 str 应该像这样转换为 LPCTSTRatol((LPCTSTR)str);

如前所述,您使用的是 Unicode。其他功能必须使用 Unicode:

long ldata = _wtol(str);

CString 声明中的某处是这样的:

#ifdef UNICODE
#define CString CStringW
#else 
#define CString CStringA
#endif

当项目编译为 Unicode 时,CString 变为宽字符 CStringW,因此您必须使用 atol 的宽字符版本,即 _wtol 并且相同每隔一个字符串函数。

atol(CStringA(xxx)) 或 _ttol

atol((LPCTSTR)str 幸运的是没有编译,但如果编译了,它可能会给出错误的结果,见下文。

有人做出了一个糟糕的决定,将 Windows Unicode 字符存储为 CString 中的 UTF16,导致了 CStringW 和 CStringA 的恐怖。 (无论如何,16 位不足以存储所有 Unicode 字符,请参见 bat 示例。)

如果您将 CString 转换为 CStringA(如果您认为这比希望编译器这样做更好,然后转换为空终止字符串指针),那么 atol 应该具有它想要的 ASCII 字符串。

软件示例中的最后一个选项没有给出 1000 的原因是 CStringW 正在为 1 存储两个字节(每个后续字符再存储两个字节)、一个 ASCII“1”和一个空字节。只需将指针转换为一个 ASCII 空终止字符串指针,就会使该字符串看起来像一个空终止字符串,其中只有一个 1。因此,请远离任何 (LPCTSTR) 建议。

原因

转换为 CStringA 应该适用于 16 位宽或 8 位宽的字符串,因此您不必使用像 #ifdef UNICODE 这样可怕的编译器指令来污染您的软件。

在可用的系统上,您可以使用 _ttol,类似于 _atol_wtol,但是(就像上面的解决方案一样)无论编译器指令 UNICODE 是否处于活动状态都会起作用。

请注意,还有其他函数,例如 _atol_l,它们可以使用语言环境定义来工作,如果您想从“400.456 德国马克”或“400,456 英镑”等字符串中读取整数,这可能会很有用。