我已经做了一些关于让UTF-8/16在cmd.exe
中正常工作的研究。我找到了这些文章:
https://alfps.wordpress.com/2011/11/22/unicode-part-1-windows-console-io-approaches/ https://alfps.wordpress.com/2011/12/08/unicode-part-2-utf-8-stream-mode/ http://www.siao2.com/2008/03/18/8306597.aspx
以及这个问题:Output unicode strings in Windows console app
救生功能为_setmode
,导致cmd.exe
为Just Work™。但实际做了什么?第一篇文章指出
Visual C ++运行时库可以在内部UTF-16和外部UTF-8之间自动转换,如果您只是通过使用适当的文件描述符编号和模式标志调用_setmode函数来执行此操作。例如,模式_O_U8TEXT导致转换为UTF-8或从UTF-8转换。
这一切都很好,但以下(对我来说)有点矛盾。 我们来看看这个简单的程序:
#include <fcntl.h>
#include <io.h>
#include <iostream>
int main(void)
{
_setmode(_fileno(stdout), _O_U16TEXT);
std::wcout << L"привет śążź Ειρήνη";
// yes, wcout; I can use both wprintf and wcout, they both seem to have the same effect
getchar();
return 0;
}
这会正确打印到控制台(当然我们选择正确的字体);没有_setmode
电话,我得到了垃圾。但这里实际翻译了什么?这个功能到底是做什么的?它是否从UTF-16转换为控制台使用的任何代码页? Windows在内部使用UTF-16,为什么首先需要转换?
此外,如果我将第二个参数更改为_O_U8TEXT
,程序的工作方式与_O_U16TEXT
一样好,这让我更加困惑; UT的UTF-16表示与UTF-8表示非常不同,那么为什么它仍然有效呢?
我应该提一下,我正在使用Visual Studio 2015(MSVC 14.0),源文件编码为带有BOM的UTF-8。