C++ std::wcout 输出乱码
遇到问题
最近使用 C++ 遇到了中文处理问题,今天下午想测试 C++ 宽字符使用时,发现如下程序并不能如愿输出汉字。
1 | int main() |
在网上多处搜索处理方法后仍不能解决,于是自己探索了一波。收获蛮大的,于是记录下。
该文章程序及结果皆在 Linux 环境下。
结论
结论是我在一些程序中总结出来的,其中若有错误,希望指正。
- Linux 下
printf和wprintf不能混用,即同时使用。具体原因可自行搜索,网上有很多资料。 - C++ 中默认情况下
std::cout与std::wcout分别与printf和wprintf同步,维护共同缓冲区。为方便理解,我们可以假设std::cout调用printf,std::wcout调用wprintf(这里只是假设,方便我们理解)。 - 综合上述 1、2 两条,可知在开启
sync_with_stdio情况下std::cout及std::wcout不能混用。 先使用std::cout后使用std::wcout会造成std::wcout输出乱码,先使用std::wcout的话std::cout压根不能输出东西。 关闭情况下两者可混用。 - C 语言库中设置
locale函数为setlocale(), C++ 语言库中设置std::locale函数为std::locale::global()。可认为 C 语言库和 C++ 库分别有不同的locale。setlocale()函数仅设置 C 语言中的locale,而std::locale::global()函数两者都会设置。 - 开启
sync_with_stdio情况下,可认为std::cout与std::wcout使用的是 C 语言中的locale。而关闭情况下则使用 C++ 自己的std::locale。 std::wcout输出中文时依靠地区locale,故我们在使用其输出中文之前要设置locale。- 在开启
sync_with_stdio情况下,想用std::wcout输出汉字要设置 C 语言中的locale,使用两种方法都可以。而关闭情况下,只能使用 C++ 的方法,且要在关闭同步之前设置,也可以使用std::wcout.imbus( std::locale("") )单独设置。
其他收获
std::cout中 c 表示字符,std::wcout中 wc 表示宽字符。
测试程序
这里展示部分测试程序及运行结果(Ubuntu 下),测试程序可根据结论中的几点自行结合测试。
开启 sync_with_stdio (默认)
1 | int main() |
??????
“你能输出中文” 共 6 个汉字,输出中共 6 个问号。 wstr 中有多少个汉字,输出中就多少个 ?
1 | int main() |
你能输出中文
1 | int main() |
你好
wcout 输出乱码
1 | int main() |
??????
cout 并不会输出
关闭 sync_with_stdio
1 | int main() |
输出为空
1 | int main() |
你能输出中文?
1 | int main() |
你好
1 | int main() |
你好
你能输出中文?