根据MSDN:
“对于 Microsoft C/C++ 编译器,源字符集和执行字符集都是 ASCII。”
C++03
2.1 翻译阶段
"..任何不在基本源字符集 (2.2) 中的源文件字符都将替换为指定该字符的通用字符名。(实现可以使用任何内部编码,只要在源文件,以及在源文件中表示为通用字符名称的相同扩展字符(即使用 \uXXXX 表示法)等价地处理。)"
2.13.2 字符文字
“通用字符名称被转换为执行字符集中命名字符的编码。如果没有这样的编码,通用字符名称被转换为实现定义的编码。”
为了测试 MSVC++ 使用哪个执行字符集,我编写了以下代码:
wchar_t *str = L"中";
unsigned char *p = reinterpret_cast<unsigned char*>(str);
for (int i = 0; i < sizeof(L"中"); ++i)
{
printf ("%x ", *(p + i));
}
输出显示2d 4e 0 0
, 和0x4e2d
是这个汉字的UTF-16 编码。所以我得出结论:UTF-16 被 MSVC 用作执行字符集(我的版本:2012 4.5.50709)
之后,我尝试将此字符打印到 Windows 控制台。由于控制台使用的默认语言环境是"C"
,因此我将语言环境设置为代码页 936,表示简体中文字符。
// use the execution environment locale setting, which is 936
wchar_t *str = L"中";
char* locale = setlocale(LC_ALL, "");
wprintf (L"%ls\n", str);
哪个输出:
中
我很好奇的是,以 UTF-16 编码的字符如何被区域设置(解码器)设置为非 UTF-16(MS 代码页 936)的 Windows 控制台解码?怎么会这样?