【问题标题】:c++, cout and UTF-8c++、cout 和 UTF-8
【发布时间】:2011-08-05 09:03:10
【问题描述】:

希望是一个简单的问题:cout 在处理以多字节 UTF-8 字符结尾的字符串时似乎死了,我做错了什么吗?这是 Win7 x64 上的 GCC (Mingw)。

**编辑对不起,如果我不够清楚,我不关心丢失的字形或字节的解释方式,只是在调用 cout << s4 后它们根本没有显示(缺少 BAR )。在第一次显示任何文字后,任何进一步的couts 都没有!

#include <cstdio>
#include <iostream>
#include <string>

int main() {
    std::string s1("abc");
    std::string s2("…");  // … = 0xE2 80 A6
    std::string s3("…abc");
    std::string s4("abc…");

    //In C
    fwrite(s1.c_str(), s1.size(), 1, stdout);
    printf(" FOO ");
    fwrite(s2.c_str(), s2.size(), 1, stdout);
    printf(" BAR ");
    fwrite(s3.c_str(), s3.size(), 1, stdout);
    printf(" FOO ");
    fwrite(s4.c_str(), s4.size(), 1, stdout);
    printf(" BAR\n\n"); 

    //C++
    std::cout << s1 << " FOO " << s2 << " BAR " << s3 << " FOO " << s4 << " BAR ";
}

// results:

// abc FOO ��� BAR ���abc FOO abc… BAR

// abc FOO ��� BAR ���abc FOO abc…

【问题讨论】:

  • 你在哪里运行你的程序? Windows 命令提示符确实不太喜欢 Unicode,因此虽然您的程序可能输出文本很好,但控制台不知道如何处理它。
  • @jalf:Windows 控制台子系统没有真正的问题。 WriteConsoleW 在给定正确字体的情况下工作得相当好。不过,Windows 不喜欢 UTF-8,这意味着 WriteConsoleA 会在这里窒息。
  • 在 Ubuntu/gnome-terminal/GCC 上为我工作。我怀疑要做到这一点需要 C++ 正确性考虑平台细节。
  • @MSalters:哦,是的,我应该更具体一点。
  • 管道输出到一个文件并在记事本中打开该文件。会发生什么?

标签: c++ utf-8 cout


【解决方案1】:

如果您希望您的程序使用您当前的语言环境,请在程序中首先调用setlocale(LC_ALL, "")。否则程序的语言环境是C,它对非ASCII字符的作用是我们人类无法知道的。

【讨论】:

  • +1 到 n.m.在 Windows 上,调用 setlocale(LC_ALL, "") 并执行 chcp 65001 是控制台中 Unicode 的诀窍
【解决方案2】:

这真的不足为奇。除非您的终端设置为 UTF-8 编码,否则它怎么知道 s2 不应该是“(带抑扬符的拉丁小写字母 a)(欧洲符号)(管道)”, 假设您的终端根据http://www.ascii-code.com/设置为ISO-8859-1

顺便说一句,cout 并没有“死亡”,因为它显然会在您的测试字符串之后继续产生输出。

【讨论】:

  • 好点。 std::cout 只向外界回显字节流。它们的解释方式取决于您和最终将读取这些字节的程序。
  • @user657267 - 是的,cout 什么也不输出,但是如果你使用 printf,那么你会得到你所期望的(除非你没有使用正确的控制台字体,并且完成了 chcp 65001
【解决方案3】:

默认情况下,Windows 控制台不处理非本地代码页字符。

您需要确保在控制台窗口中设置了支持 Unicode 的字体,并通过调用 chcp 将代码页设置为 UTF-8。但是,这并不能保证成功。 请注意,如果控制台无法显示花哨的字符,则 `wcout' 不会改变任何内容,因为它的字体是拙劣的。

在所有现代 Linux 发行版上,控制台都设置为 UTF-8,这应该可以开箱即用。

【讨论】:

    【解决方案4】:

    正如其他人指出的那样,std::cout 对此是不可知的,至少在"C" 语言环境(默认)中是这样。另一方面,您的控制台窗口必须设置为显示 UTF-8:代码页 65001。在执行程序之前尝试调用 chcp 65001。 (过去这对我有用。)

    【讨论】:

      猜你喜欢
      • 2014-12-02
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 2013-09-11
      • 2011-06-17
      • 2020-12-09
      • 2012-08-18
      • 2017-05-07
      相关资源
      最近更新 更多