摘要:我应该怎么做才能将源代码中定义的以 UTF-8 编码 (Windows CP 65001) 存储的字符串文字正确打印到使用流的cmd
控制台?std::cout
动机:我想修改优秀的Catch 单元测试框架(作为一个实验),以便它显示我的带有重音字符的文本。修改应该简单、可靠,并且对其他语言和工作环境也应该有用,以便作者可以接受它作为增强。或者,如果您知道 Catch 并且如果有其他解决方案,您可以发布吗?
详情:我们先从捷克版的“快棕狐……”开始吧
#include <iostream>
#include "windows.h"
using namespace std;
int main()
{
cout << "\n-------------------------- default cmd encoding = 852 -------------------\n";
cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << endl;
cout << "\n-------- Windows Central European (1250) set for the cmd console --------\n";
SetConsoleOutputCP(1250);
std::cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << std::endl;
cout << "\n------------- Windows UTF-8 (65001) set for the cmd console -------------\n";
SetConsoleOutputCP(CP_UTF8);
std::cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << std::endl;
}
它打印以下内容(字体设置为 Lucida Console):
默认编码为 852 ,cmd
默认 windows 编码为 1250,源代码使用 65001 编码(带有 BOM 的 UTF-8)保存。SetConsoleOutputCP(1250);
更改编码(以编程方式)的方式与更改cmd
编码相同chcp 1250
。
观察:设置1250编码时,UTF-8字符串文字打印正确。相信是可以解释的,但是真的很奇怪。有什么体面的、人性化的、通用的方法来解决这个问题吗?
更新:在我的"narrow string literal"
情况下使用 Windows-1250 编码存储(中欧的本地 Windows 编码)。它似乎与源代码的编码无关。编译器将其保存在windows 本机编码中。因此,切换cmd
到该编码可以提供所需的输出。这很丑陋,但是我怎样才能以编程方式获取本机 Windows 编码(将其传递给SetConsoleOutputCP(cpX)
)?我需要的是一个对发生编译的机器有效的常量。它不应该是运行可执行文件的机器的本机编码。
也引入了 C++11 u8"the UTF-8 string literal"
,但似乎不适合SetConsoleOutputCP(CP_UTF8);