【问题标题】:Working with UTF-8 std::string objects in C++在 C++ 中使用 UTF-8 std::string 对象
【发布时间】:2020-02-01 08:40:32
【问题描述】:

我在Windows 上使用Visual StudioC++ 来处理像ʜᴇʟʟᴏ ꜱᴛᴀᴄᴋᴏᴠᴇʀꜰʟᴏᴡ 这样的小型大写字母文本,例如使用this 网站。每当我从文件中读取此文本或使用std::string 将此文本直接放入我的源代码时,Visual Studio 中的文本可视化器会以错误的编码显示它,大概可视化器使用Windows (ANSI)。如何强制Visual Studio 让我正确使用UTF-8 字符串?

std::string message_or_file_path = "...";
auto message = message_or_file_path;

// If the file path is valid, read from that file
if (GetFileAttributes(message_or_file_path.c_str()) != INVALID_FILE_ATTRIBUTES
    && GetLastError() != ERROR_FILE_NOT_FOUND)
{
    std::ifstream file_stream(message_or_file_path);
    std::string text_file_contents((std::istreambuf_iterator<char>(file_stream)),
        std::istreambuf_iterator<char>());
    message = text_file_contents; // Displayed in wrong encoding
    message = "ʜᴇʟʟᴏ ꜱᴛᴀᴄᴋᴏᴠᴇʀꜰʟᴏᴡ"; // Displayed in wrong encoding
   std::wstring wide_message = L"ʜᴇʟʟᴏ ꜱᴛᴀᴄᴋᴏᴠᴇʀꜰʟᴏᴡ"; // Displayed in correct encoding
}

我尝试了额外的命令行选项/utf-8 来编译和设置语言环境:

std::locale::global(std::locale(""));
std::cout.imbue(std::locale());

这些都没有解决编码问题。

【问题讨论】:

  • .cpp文件的编码是什么?
  • 您应该以二进制模式打开std::ifstream,以避免在读取chars 时发生任何数据转换。这至少可以确保std::string 具有正确的字节。不过,这并不意味着 IDE 会正确显示它。否则,请改用std::wstring,正如您已经发现的那样。您可以使用带有 UTF-8 语言环境 imbue()std::wifstream 来阅读它。或者先读取原始字节,然后使用MultiByteToWideChar()std::wstring_convert 将字节转换为std:::wstring

标签: c++ windows visual-studio encoding utf-8


【解决方案1】:

What’s Wrong with My UTF-8 Strings in Visual Studio?,有几种方法可以查看std::string 的内容,使用UTF-8 编码。

假设您有一个具有以下初始化的变量:

std::string s2 = "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9f\x8d\x8c";

使用监视窗口。

  • 将变量添加到 Watch。
  • 在 Watch 窗口中,将 ,s8 添加到变量名称以将其内容显示为 UTF-8。

这是我在 Visual Studio 2015 中看到的内容。

使用命令行窗口。

  • 在命令行窗口中,使用 ? &amp;s2[0],s8 将文本显示为 UTF-8。

这是我在 Visual Studio 2015 中看到的内容。

【讨论】:

  • 这可能适用于文本可视化器,但它不会更正代码的编码,因此它只是一个半解决方案。不过,你值得你的支持。
  • @BullyWiiPlaza,“代码的编码”是什么意思?
  • @R Sahu:我的意思是在处理代码期间,字符串将无法正常工作。我例如将 unicode 文本 std::string 对象复制到剪贴板,当我粘贴它时,它搞砸了。使用std::wstring 版本可以正常工作。
【解决方案2】:

一个可行的解决方案是简单地将所有std::strings 重写为std::wstrings 并正确调整代码逻辑以与std::wstrings 一起使用,如问题中所示。现在一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2011-11-01
    • 2011-04-06
    • 2013-09-11
    • 1970-01-01
    相关资源
    最近更新 更多