我有以下 C++ 代码:
#include "stdafx.h"
#include <atlstr.h>
int _tmain(int argc, _TCHAR* argv[])
{
CString OFST_PATH;
TCHAR DIR_PATH[MAX_PATH];
GetCurrentDirectory(MAX_PATH, DIR_PATH);
OFST_PATH.Format(DIR_PATH);
CHAR *pOFST_PATH = (LPSTR)(LPCTSTR)OFST_PATH;
return 0;
}
我想明白为什么程序末尾pOFST_PATH
的值为“c”? (LPSTR)(LPCTSTR)
变量 OFST_PATH
的转换对写入其中的整个路径做了什么?
正如您在以下窗口中看到的,调试时变量值是:
最佳答案
CString
和 LPCTSTR
都基于 TCHAR
,即 wchar_t
什么时候UNICODE
已定义(在您的情况下,我可以通过调试器中 argv
的值判断)。当您这样做时:
(LPCTSTR)OFST_PATH
这没问题,因为 CString
有一个到 LPCTSTR
的转换运算符.但是用UNICODE
定义,LPCTSTR
是LPCWSTR
,又名 wchar_t const*
.它指向一个 utf16 字符数组。该数组中的第一个字符是 L'c'
(这是 'c'
的宽字符版本)。 L'c'
的字节数在内存中看起来像这样:0x63 0x00
.这是字母“c”的 ASCII 代码,后跟一个零。因此,当您转换 CString
至 LPCTSTR
,这是有效的,但是,您的下一次转化:
(LPSTR)(LPCTSTR)OFST_PATH
那是无效的。 LPSTR
是char*
, 所以你正在治疗 wchar_t const*
就好像它是一个 char*
.那么你的调试器假设当它看到一个 char*
,它正在查看以空字符结尾的窄字符串。如果您还记得上面第一个字符的字节值是什么,它就是字母“c”的 ASCII 值,后跟一个零。因此调试器将其视为仅由字母“c”组成的空终止字符串。
这个故事的寓意是,如果您不了解它们的作用以及它们是否合适,请不要使用 C 风格的转换。
关于c++ - 如何将 `CString` 转换为 `CHAR *` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37908311/