【问题标题】:C++ - std::wstring to std::string - quick and dirty conversion for use as key in std::mapC++ - std::wstring 到 std::string - 快速而肮脏的转换,用作 std::map 中的键
【发布时间】:2013-02-26 07:33:49
【问题描述】:

我正在寻找一些关于将 std::wstring 转换为 std::string 的最佳方法的建议 - 但这是一种快速而肮脏的转换,可用作 std::map<std::string, int> 对象中的键。

地图很大,已经很好集成到项目中了,只有少数几个key需要这个转换,所以我觉得把地图改成这样会很浪费一个接受std::wstring 作为键的。

转换的输出并不重要,但它必须保持一致,以便每次都能可靠地从映射中提取正确的值。

该应用程序是一个仅限 Windows 的应用程序。

是否有任何已知的过程可以为此目的可靠地进行粗略转换?或者最好的方法是通过通常的、适当的转换过程(如本 SO 问题/答案中所述:How to convert wstring into string?)?

编辑:请记住 - 只要事情是一致的,丢失信息是可以的。即,如果我输入一些日文字符,并且它们始终转换为相同的(可能是垃圾)std::string,那很好。这永远不会用于显示,仅用作从地图中提取值的键。

谢谢!

【问题讨论】:

  • 一个adapter?
  • 也许您应该将std::wstring 转换为UTF-8,并将std::string 设置为该值。这样可以避免虚假的 '\0' 字节。
  • 你为什么要使用std::wstringUse UTF8 everywhere.
  • @Arne Mertz:感谢您提供该文章的链接。有趣的阅​​读。但是要回答您的问题:在这种情况下别无选择:P

标签: c++ stdstring


【解决方案1】:

如果你对内容的语义不感兴趣,而只是为了让内容具有可比性,我将把内部 wchar[] 凝聚成双倍大小的 char[] 并用它来初始化字符串(通过在构造函数中指定地址/大小)

std::wstring ws(L"ABCD€FG");
std::string s((const char*)&ws[0], sizeof(wchar_t)/sizeof(char)*ws.size());

现在s 是不可打印的(它可能包含空字符),但仍然可以分配和比较。

你可以返回:

std::wstring nws((const wchar_t*)&s[0], sizeof(char)/sizeof(wchar_t)*s.size());

现在比较

std::cout << (nws==ws)

应该打印1

但是,请注意,由于 0 的存在,地图中的顺序(operator&lt; 的结果)是……模糊的,并且不反映任何文本语义。然而搜索仍然有效,因为——无论多么模糊——它仍然是一个“订单”。

【讨论】:

  • 这会分散 OP 的注意力:重点显然不是要打印出漂亮的文件,而是要检查在一个循环中不会出现信息丢失。取决于相等性而改变的任何输出都发挥相同的作用。我做的更短更简单,不需要额外的标题。由 OP 为他的需要找到最好的“美化器”(包括用 MessageBox 替换 cout 或显示他想要的任何内容的任何对话框)
  • 如果这是一个 unordered_map,我会担心字符串中的空字节。如果散列函数对字符串有专门化,它可能会也可能不会尊重实际的 std::string 大小,而是在第一个空字节处停止。
【解决方案2】:

作为一个变种,我会选择

std::wstring w( L"Some" );
std::string s( w.begin(), w.end() );

也许另一个答案更快(取决于字符串迭代器的实现),但这对我来说是一种更标准的方式。但是,是的,这会丢失一些独特的字符。

【讨论】:

  • 是的,在进行字符串转换时到处丢失一些字符通常没什么大不了的! ;)
  • @mrt 如果您阅读了这个问题,它要求“快速而肮脏的转换”和“转换的输出并不重要”,只有“它必须是一致的”。还有一个完整的编辑添加,它准确地描述了“只要事情是一致的,丢失信息就可以了”和“转换成相同的(可能是垃圾)字符串”,还有“这永远不会用于显示”。
  • 不,不要这样做。它仅适用于英语。它会破坏中文、日文等文本。
【解决方案3】:

您可以将 std::wstring 转换为 utf-8(使用 WideCharToMultiByte 或类似这个库:http://utfcpp.sourceforge.net/),即一个以空值结尾的 c-string,然后从中构造 std::string。这种转换是可逆的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多