首页 > 解决方案 > 在 C++ 中将 utf8 wstring 转换为 windows 上的字符串

问题描述

我用 boost::filesystem::path 表示文件夹路径,它是 Windows 操作系统上的 wstring,我想使用以下方法将其转换为 std::string:

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv1;
shared_dir = conv1.to_bytes(temp.wstring());

但不幸的是,以下文本的结果是这样的:

"c:\git\myproject\bin\árvíztűrőtükörfúrógép" -> "c:\git\myproject\bin\árvÃztűrÅ'tükörfúrógép"

我做错了什么?

#include <string>
#include <locale>
#include <codecvt>

int main()
{
    // wide character data
    std::wstring wstr =  L"árvíztűrőtükörfúrógép";

    // wide to UTF-8
    std::wstring_convert<std::codecvt_utf8<wchar_t>> conv1;
    std::string str = conv1.to_bytes(wstr);
}

我在 Visual Studio 调试模式下检查变量的值。

标签: c++string

解决方案


代码很好。

您正在使用wstring存储 UTF-16 编码数据的存储空间,并创建string存储 UTF-8 编码数据的存储空间。

我在 Visual Studio 调试模式下检查变量的值。

Visual Studio 的调试器不知道您的字符串存储 UTF-8。Astring只包含字节。只有您(以及阅读您的文档的人!)知道您将 UTF-8 数据放入其中。你可以在里面放点别的东西。

因此,如果没有更明智的做法,调试器只会将字符串呈现为 ASCII*。您看到的是字符串中字节的 ASCII* 表示。

这里没有错。

如果您要输出类似 的字符串std::cout << str,并且在设置为 UTF-8 的命令行窗口中运行程序,您将得到预期的结果。此外,如果您检查字符串中的各个字节,您会发现它们被正确编码并保持您想要的值。

不过,您可以根据需要推动 IDE 将字符串解码为 UTF-8:在 Watch 窗口中输入str,s8; 或者,在命令窗口中,键入? &str[0],s8. Giovanni Dicanio 在他的文章“ Visual Studio 中我的 UTF-8 字符串有什么问题? ”中探讨了这些技术。


它甚至不是真正的 ASCII;它将是由您的系统决定的一些 8 位编码,很可能是给定平台的代码页Windows-1252 。ASCII 只定义低 7 位。从历史上看,各种 8 位代码页在各种设置中被通俗地(如果不正确)称为“扩展 ASCII”。但关键是,将字符串渲染到屏幕的组件根本没有考虑数据的多字节性质,更不用说它的 UTF-8 特性了。


推荐阅读