【问题标题】:how to convert or cast CString to LPWSTR?如何将 CString 转换或转换为 LPWSTR?
【发布时间】:2013-09-21 05:01:22
【问题描述】:

我尝试使用此代码:

USES_CONVERSION;
LPWSTR temp = A2W(selectedFileName);

但是当我检查temp 变量时,只需获取第一个字符

提前致谢

【问题讨论】:

  • 这是 ANSI 还是 Unicode 版本?
  • 您对问题的描述非常狭窄。请解释您要做什么以及变量包含什么。
  • selectedFileNameCStringA 还是 CStringW
  • 我真的不知道是ANSI还是UniCode,我是C#程序员,现在我遇到了C++的麻烦...我在VS2012中有一个项目,使用C++作为语言,该项目编译一个嵌入网页的OCX。从调用 OCX 中现有功能的页面。在这种特殊情况下,一个函数应该引发一个对话框,并选择一个文件,该文件必须(作为字符串)返回到网站。在 OCX 映射定义中,我只能指定像 LPWSTR 或 LPCTSTR 这样的句子,但不能指定像 CString 这样的简单类型。正如我之前所说,我是 C++ 新手。所以我需要将 CString 转换为 LPWSTR
  • CString 包裹 LPTSTR,CStringW 包裹 LPWSTR,CStringA 包裹 LPSTR。如果你有一个 CString,并且需要将它传递给一个接受 LPCTSTR 的函数,只需传递它。 CString 隐式转换为 LPCTSTR。

标签: c++ winapi mfc


【解决方案1】:

如果我没记错的话,CString 的类型定义为 CStringACStringW,具体取决于您是否在构建 Unicode。

LPWSTR 是“指向宽字符串的长指针”——又名:wchar_t*

如果您想将CString 传递给采用LPWSTR 的函数,您可以这样做:

some_function(LPWSTR str);

// if building in unicode:
some_function(selectedFileName);

// if building in ansi:
some_function(CA2W(selectedFileName));

// The better way, especially if you're building in both string types:
some_function(CT2W(selectedFileName));

但是 LPWSTR 是对字符串的非常量访问。您是否正在使用尝试修改字符串的函数?如果是这样,您想使用实际缓冲区,而不是 CString

另外,当你“检查”temp 时——你是什么意思?你试过cout << temp吗?因为那行不通(它只会显示第一个字符):

char 每个字符使用一个字节。 wchar_t 每个字符使用两个字节。对于纯英语,当您将其转换为宽字符串时,它使用与原始字符串相同的字节,但每个字符都用零填充。由于NULL 终止符也是零,如果您使用较差的调试器或 cout(使用 ANSI 文本),您将只能看到第一个字符。

如果要将宽字符串打印到标准输出,请使用wcout

【讨论】:

  • 嗨,谢谢你的回复。我的意思是,在从网页调用的函数中,我只得到字符串的第一个字符(在这种情况下是所选文件),即字母“C”是我从中获取存档名称的驱动器。显然将 CString 转换为 LPWSTR 丢失了字符串的其余部分
  • @Luis 我怀疑有什么东西丢失了。只是你不明白 UNICODE 字符串在 Windows 中是如何编码的。请务必阅读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)。完成后,您将了解为什么字符串需要不同的Format Specifiers。你应该使用su
  • UNICODE: CString cstring = "some"; LPWSTR lpwstr = cstring .GetBuffer(cstring .GetLength());
  • MULTICHAR: CString cstring = "some"; LPWSTR lpwstr = CT2W(cstring);
【解决方案2】:

我知道这是一个相当老的问题,但我也有同样的问题,以前的答案都对我有用。

不过,这确实适用于我的 unicode 构建:

LPWSTR temp = (LPWSTR)(LPCWSTR)selectedFileName;

【讨论】:

    【解决方案3】:

    简而言之:你不能。如果您需要指向 CString 对象的底层字符缓冲区的非常量指针,则需要调用 GetBuffer

    如果你需要一个 const 指针,你可以简单地使用static_cast<LPCWSTR>(selectedFilename)

    【讨论】:

    • 只有在程序使用UNICODE 标志构建时才有效,该标志将TCHAR 映射到wchar_t。如果该标志未打开,则它是char,因此进行静态转换不会给您想要的东西。由于CStringoperator LPCTSTR() 有重载,因此无需使用static_cast - 它会隐式进行转换。
    • @Zac 你真是太聪明了。感谢您指出显而易见的。而且也不正确...CStringT 没有operator LPCTSTR() overload。它的基类CSimpleStringT 定义了operator PCXSTR。是否需要static_cast 是编译器警告级别和构建工具集的问题。随意省略它。
    • 在你努力挑起战斗时,你完全没有抓住重点。 LPCTSTR = "指向常量 t 字符串的长指针"。 PCXSTR = "pointer to a const x-string" 其中x 是根据CSimpleString<> 声明的模板参数填充的。也就是说,如果没有定义UNICODE,CString基本上就是CSimpleString<char>,所以尝试使用static_cast<LPCWSTR>是行不通的,这是你遗漏的,也是我要指出的。
    • @Zac 既然你这么厉害,那你为什么不提供你自己的答案呢?我的意思是,给 一个机会来无缘无故地对你的投票投反对票。这只是公平的,不是吗?
    • 我对你的投了反对票,因为它不完整。我接着描述了如何修复它。你似乎把事情看得很个人化,这很难看出(不像你),我不是在攻击你,而是注意到你需要添加什么来修复它。由于蒂姆已经发布了一个完整的答案,我不需要重新发布已经写好的和正确的答案。但是,如果您觉得自己的帖子更好,请随意对他的帖子投反对票。
    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2016-06-07
    • 2011-10-15
    • 2023-04-01
    • 2011-11-23
    • 2012-03-07
    • 2011-07-29
    • 2014-11-27
    相关资源
    最近更新 更多