C++ 从 std::string 创建 CString 失败

C++ creating CString from std::string fails

在我基于 MFC 的应用程序中,这段代码:

std::string stdString("MappingName");
std::cout << "as String: " << stdString << std::endl;
CString cString(stdString.c_str());
std::cout << "as CString: " << cString << std::endl;

产生这个输出:

as String: MappingName
as CString: 01DEA060

每次运行它的CString的值都不一样,但是长度好像是恒定的。其他一些结果是 042219B0042C4378

我已经尝试了 this thread 中讨论的所有变体,结果都是一样的。我还尝试将 Visual Studio 项目中的字符集从 Use Unicode Character Set 更改为 Use Multi-Byte Character Set , 再次无效。

转换失败的原因可能是什么?

编辑: 更多测试表明 std::string 的值似乎没有什么不同:

tmp as String: The quick brown fox jumps over the lazy dog
tmp as CString: 00EAAF88

我还将字符集设置为未设置,这也没有帮助。

问题是打印而不是转换。

CString 可以隐式转换为 TCHAR const*。在启用 unicode 的情况下构建时,这是 wchar_t const*.

std::cout 没有 <<wchar_t const* 重载。它确实有一个 void const* 过载。

void 指针重载以十六进制打印指针地址。

在打印前转换为 CStringA

std::cout << "as CString: " << static_cast<CStringA>(cString) << std::endl;

或使用wcout打印。

这个问题是两个方面的结合:

  • 具有显式编码 (std::string) 和通用文本映射(CStringCStringA/CStringW)的字符串类型的混合。
  • CString通过conversion c'tors.
  • 在编码之间进行转换的能力

std::string转换成CString就好了,估计是构造了一个CStringW对象。由于 std::ostream 没有 operator<< 重载,它采用 wchar_t const*CStringW implicitly converts to),它仅打印地址,匹配通用 void const* 过载。

这里的解决方案是将通用文本映射从图片中取出,并构建一个匹配源编码的 CString 专业化(std::string 的 ANSI,即 CStringA) :

std::string stdString("MappingName");
std::cout << "as String: " << stdString << std::endl;
CStringA cString(stdString.c_str());
std::cout << "as CString: " << cString.GetString() << std::endl;

要在构造 CString 时获得有关隐式转换的通知,您可以 #define _CSTRING_DISABLE_NARROW_WIDE_CONVERSION 处理器符号。如果您尝试调用任何转换 c'tors,这将反过来生成编译器错误。