使用std :: codecvt_xxx将C ++ std :: wstring转换为utf8

时间:2016-05-29 20:12:55

标签: c++ string windows utf-8 widechar

C ++ 11具有将宽字符串std::wstring从/转换为utf8表示的工具:std::codecvtstd::codecvt_utf8std::codecvt_utf8_utf16等。

Windows应用程序可以使用哪一个将常规宽字符串Windows字符串std::wstring转换为utf8 std::string?它是否总是在没有配置区域设置的情况下工作?

2 个答案:

答案 0 :(得分:4)

取决于你如何转换它们 您需要指定源编码类型和目标编码类型 wstring不是格式,只是定义数据类型。

现在通常当一个人说“Unicode”时,一个意味着UTF16这就是 Microsoft Windows 所使用的,这通常是wstring包含的内容。

因此,从UTF8转换为UTF16的正确方法是:

     std::string utf8String = "blah blah";

     std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
     std::wstring utf16String = convert.from_bytes( utf8String );

反过来说:

     std::wstring utf16String = "blah blah";

     std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
     std::string utf8String = convert.to_bytes( utf16String );

增加了混乱:
当您在 Windows 平台上使用std::string时(例如,当您使用多字节编译时),它不是 UTF8 。他们使用 ANSI 更具体地说,是Windows正在使用的默认编码语言。

另请注意wstring is not exactly the same as UTF-16

在Unicode中编译时,windows API命令需要以下格式:

命令 A - 多字节 - ANSI
命令 W - Unicode - UTF16

答案 1 :(得分:2)

似乎std::codecvt_utf8适用于转化std::wstring - &gt; utf8。它通过了我所有的测试。 (Windows应用程序,Visual Studio 2015,带有EN语言环境的Windows 8)

我需要一种将文件名转换为UTF8的方法。因此,我的测试是关于文件名。

在我的应用中,我使用boost::filesystem::path 1.60.0来处理文件路径。它运行良好,但无法正确转换文件名为UTF8。 内部Windows版boost::filesystem::path使用std::wstring来存储文件路径。不幸的是,std::string的内置转换效果不佳。

测试用例:

  • 使用混合符号c:\test\皀皁皂皃的(一些随机亚洲符号)创建文件
  • 使用boost::filesystem::directory_iterator扫描目录,获取文件的boost::filesystem::path
  • 通过内置转化std::string
  • 将其转换为filenamePath.string()
  • 你得到c:\test\?????。亚洲符号转换为&#39;?&#39;。不好。

boost::filesystem在内部使用std::codecvt。它不适用于转化std::wstring - &gt; std::string

您可以将转化功能定义为original snippet),而不是内置boost::filesystem::path转换:

std::string utf8_to_wstring(const std::wstring & str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.to_bytes(str);
}

然后您可以轻松地将文件路径转换为UTF8:utf8_to_wstring(filenamePath.wstring())。它运作得很好。

适用于任何文件路径。我测试了ASCII字符串c:\test\test_file,亚洲字符串c:\test\皀皁皂皃的,俄语字符串c:\test\абвгд,混合字符串c:\test\test_皀皁皂皃的c:\test\test_абвгдc:\test\test_皀皁皂皃的_абвгд。对于每个字符串,我都会收到有效的UTF8表示。