_setmode实际翻译了什么?

时间:2015-11-07 22:00:34

标签: windows visual-c++ character-encoding msvcrt

我已经做了一些关于让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。

0 个答案:

没有答案