C++字符有四个类型,char是1字节,wchar_t可能是2字节或4字节,char16_t和char32_t顾名思义。char和wchar_t是C++98就有的,支持也最好。char16_t和char32_t是C++11加入的,直到现在也没有很好的支持。
由于emoji这种东西的出现,支持Windows-1252/GBK/Big5已经不够用了,要支持Unicode。但是Windows中char编码是定死的,不支持Unicode。要想支持Unicode,不是说其它方法不行,而是使用wchar_t作为字符类型是最方便的做法。
iostream宽字符流对象,虽然在Windows下不支持Unicode,但是它们是写作wchar_t程序的必备武器,这是因为字符输入输出是最简单常用的程序交互形式,它们可进行编码自动转换,解决了wchar_t的交互问题,并且所有平台都有提供,不需要学习平台相关的API。
但是iostream库在Linux下有一个坑,默认情况下wcout和cout不能混用。这是因为受到Linux下的C语言stdio.h库的掣肘:
不过实际上,只要提前调用了ios::sync_with_stdio(false),wcout和cout便不会通过stdio.h进行输入输出,而是自己管理缓冲区,就避免了wcout和cout不能混用的问题。
<code class="language-cpp">#include <iostream> #include <locale> using namespace std; int main() { // 不使用stdio.h进行输入输出,避免Linux/macOS下libc的宽窄流限制 ios::sync_with_stdio(false); // 设置locale locale::global(locale("")); cout.imbue(locale()); wcout.imbue(locale()); // 现在可以混用cout和wcout了 cout << "Hello, 窄 world!" << endl; wcout << L"Hello, 宽 world!" << endl; return 0; } </locale></iostream></code>
如果只更改编码,不更改区域格式的话:
<code class="language-cpp">locale::global(locale(locale("C"), new codecvt_byname<wchar_t, char, mbstate_t>(""))); </wchar_t,></code>
实际测试中,Ubuntu 16.04下的GCC和Windows下的Visual C++ 2017、Visual C++ 2008、Mac OS X 10.11下的Clang均通过了测试,正确输出了两个字符串。
一些非常老的Mac OS X可能会报locale("")错误,但是现在所有新版Mac OS X或macOS都是用的Clang编译器,已完全不存在这个问题。
Visual C++ 2005比较特殊。这个版本的iostream本身就有bug,只要设置locale以后cout和wcout就都没办法输出中文字符串了,不过只对控制台是有bug的,对文件没有。因此如果要兼容这个版本的话,最好配合ReadConsole/WriteConsole使用。不过,大部分情况下,我们都可以改用Visual C++ 2008来解决这个问题。
Ubuntu 16.04下的GCC输出结果(Mac OS X 10.11下的Clang差不多,从略):
<code class="language-sh">pc@DESKTOP-PNUCILD:~$ g++ abc.cpp pc@DESKTOP-PNUCILD:~$ ./a.out Hello, 窄 world! Hello, 宽 world! pc@DESKTOP-PNUCILD:~$ </code>
Windows 10 Build 15063下Visual C++ 2017输出结果:
<code class="language-bat">D:\>cl /EHsc abc.cpp Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25019 for x86 Copyright (C) Microsoft Corporation. All rights reserved. abc.cpp Microsoft (R) Incremental Linker Version 14.10.25019.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:abc.exe abc.obj D:\>abc Hello, 窄 world! Hello, 宽 world! D:\> </code>
Windows 10 Build 15063下Visual C++ 2008输出结果:
<code class="language-bat">D:\>cl /EHsc abc.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. abc.cpp Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:abc.exe abc.obj D:\>abc Hello, 窄 world! Hello, 宽 world! D:\> </code>
Windows 10 Build 15063下Visual C++ 2005输出结果:
<code class="language-bat">D:\>cl /EHsc abc.cpp 用于 80x86 的 Microsoft (R) 32 位 C/C++ 优化编译器 14.00.50727.42 版 版权所有(C) Microsoft Corporation。保留所有权利。 abc.cpp Microsoft (R) Incremental Linker Version 8.00.50727.42 Copyright (C) Microsoft Corporation. All rights reserved. /out:abc.exe abc.obj D:\>abc Hello, Hello, D:\>abc > abc.txt D:\>type abc.txt Hello, 窄 world! Hello, 宽 world! D:\> </code>
[修改于 7年6个月前 - 2017/06/13 01:01:55]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |