问题 cout


为什么

cout<< "привет";

效果很好

wcout<< L"привет";

才不是? (在Qt Creator for linux中)


1721
2017-09-07 16:57


起源

据推测,因为无论接收那些字符作为输出“不理解宽字符”。如果你更多地描述“不工作”,它可能会有所帮助。 - Mats Petersson
它打印????而是在终端窗口。但是“привет”如何才能成为unicode? - user2029077
итебе“привет” - vladkras


答案:


GCC和Clang默认将源文件视为UTF-8。您的Linux终端很可能也配置为UTF-8。所以 cout<< "привет" 有一个UTF-8字符串,用UTF-8终端打印,一切都很好。

wcout<< L"привет" 取决于一个正确的 语言环境 配置,以便将宽字​​符转换为终端的字符编码。需要初始化Locale才能使转换工作( 默认的“经典”又名“C”语言环境 不知道如何转换宽字符)。使用 std::locale::global (std::locale ("")) 使Locale匹配环境配置或 std::locale::global (std::locale ("en_US.UTF-8")) 使用特定的区域设置(类似于这个C例子)。

这是工作计划的完整来源:

#include <iostream>
#include <locale>
using namespace std;
int main() {
  std::locale::global (std::locale ("en_US.UTF-8"));
  wcout << L"привет\n";
}

g++ test.cc && ./a.out 这打印“привет”(在Debian Jessie上)。

也可以看看 这个答案 关于在标准输出中使用宽字符的危险。


14
2017-09-07 17:25



原因是符合C,C ++和POSIX标准。 - AProgrammer
谢谢。然而令人惊讶的是,“привет”不应该是std literal char[]。 - user2029077
@MinimusHeximus:默认情况下,“привет”是UTF-8中的char [],然而,L“привет”是UTF-16,UTF-32或UCS-2中的wchar []。 - ArtemGr
上面的代码在Windows gnu g ++中编译,输出此错误: terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not valid。 - Salvador
@Salvador么?问题是关于Linux。如果您的GCC端口没有“en_US.UTF-8”语言环境,则捕获异常并使用 std::locale::global (std::locale ("")) 或安装语言环境。 - ArtemGr