【发布时间】:2018-11-10 00:19:30
【问题描述】:
我正在阅读著名的answer 关于 string 和 wstring 的内容,但遇到了一些困惑。
source charset 和 execution charset 均设置为 utf-8,Windows x64,VC++ 编译器,git bash 控制台(可打印 unicode 字符),系统默认代码页 936(GB2312)。
我的专家代码:
#include <cstring>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
wchar_t c[] = L"olé";
wchar_t d[] = L"abc";
wcout << c << endl;
wcout << d << endl;
return 0;
}
可以打印“abc”,但不能打印“é”。
我了解wchar_t 与L 前缀字符串文字一起使用。在 Windows 下,wchar_t 使用 UTF-16 编码(硬编码对吗?无论我选择什么源字符集或执行字符集,L"abc" 将始终具有相同的 UTF-16 代码单元)。
问题是:wcout怎么可能是一个UTF-16编码的字符串(“abc”),而我的源文件是utf-8,执行字符集是utf-8。除非我将所有内容都设置为 utf-16,否则程序应该无法识别 UTF-16 编码的内容。
如果它可以以某种方式打印 UTF-16,那为什么它不能打印é?
【问题讨论】:
-
我还没有测试过自己,因为这些天我无法在我的机器上编译 c++(我感到羞耻)。但我发现你的问题非常有趣,我用谷歌搜索了一下。我认为 M.M 是对的,这与控制台功能有关。查找特定于 Windows 的 _setmode(_fileno(stdout), _O_U16TEXT);... 我猜测 wcout 不会简单地转发 wchar_t* 而是进行一些翻译,这就是您看到正确打印某些字符而不是 é 的方式。
-
是的,我知道 Windows 控制台不支持 utf-8。于是我在Git bash上试了一下(我觉得支持utf-8)。 windows控制台不是根本不支持utf-x吗?
-
Windows 控制台似乎支持 utf-8 字符,你可以在你的 cmd 上粘贴俄罗斯字符。我认为 wcout 可以轻松打印“abc”,因为在 ASCII、UTF-8 和 UTF-16 中,“a”在最后一个字节中编码为 0x61。 “b”和“c”几乎相同。但是 UTF-16 中的 "é" 是以 0xe9 结尾的,没有 UTF-8 字符以 0xe9 结尾。我想在 UTF-16 中的“é”和 UTF-8 中的“é”之间没有遗留或琐碎的翻译。如果您打算发送 UTF-16(并使用非传统字符),则需要将控制台设置为应用程序的标准输出