c++ 如何将'CString'转换为'CHAR *'?

w8biq8rn  于 2023-01-03  发布在  其他
关注(0)|答案(1)|浏览(186)

我有下面的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"?变量OFST_PATH(LPSTR)(LPCTSTR)强制转换对写入其中的整个路径做了什么?
正如您在下面的窗口中所看到的,调试时变量值为:

z9smfwbn

z9smfwbn1#

CStringLPCTSTR都基于TCHAR,当定义UNICODE时,TCHARwchar_t(在您的例子中,我可以通过调试器中argv的值来判断它是wchar_t)。

(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

这是无效的。LPSTRchar*,因此您将wchar_t const*视为char*。您的调试器假设当它看到char*时,它正在查看以空结尾的窄字符串。如果您还记得上面第一个字符的字节值是什么,它是字母'c'的ASCII值,后面跟着一个零。因此调试器将其视为仅由字母'c'组成的空终止字符串。
这个故事的寓意是,如果你不明白c风格的造型是做什么的,以及它们是否合适,就不要使用它们。

相关问题