老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>
如果想输出中文,就老老实实的用宽字符,第一步,设置地区,第二步,关闭与C的io流同步。
我原先实现中文输出,是将编译文件用GBK编码保存。
当我想用UTF8编码输出中文的时候,在vscode中调试时是正常的,在cmd中就是乱码。
也就是说,vscode的终端和cmd终端不是一种设置,这是Windows的老梗了,破不了。
#include <cstdio>
#include <clocale>
#include <iostream>
int main()
{
setlocale(LC_ALL, "");
std::ios::sync_with_stdio(false);
wchar_t wstr[] = L"你能输出中文?";
char str[] = "你能输出中文?";
std::wcout << wstr << std::endl;
wprintf(L"%ls\n", wstr);
std::cout << str << std::endl;
printf("%s\n", str);
return 0;
}
以上代码,在vscode中调试时结果:
ģ
ģ
你能输出中文?
你能输出中文?
在cmd中是:
Microsoft Windows [版本 10.0.19044.1586]
(c) Microsoft Corporation。保留所有权利。
E:\C++>e:\C++\suanfa\SuanFaJiChu_198.exe
你能输出中文?
你能输出中文?
浣犺兘杈撳嚭涓枃锛?
E:\C++>
用windows敲代码,涉及中文要小心。
补充一下有关Windows的老梗:
linux的终端一般使用utf8编码,而中文windows,由于各种原因,其终端都是用936编码,也就是中文地区编码。
由于方便,或不熟悉宽字符的运用,大多数开发者都使用ASCII来“模拟”宽字符,但是这里陷阱重重。
最简单的解决方法是用GBK编码存储编译,此时,你在Windows终端下是可以看到正确的输出中文的,但是输入的中文最终究竟是个啥,我也不太清除,在我的环境下,是乱码。
为了追求彻底解决,有些人试图更改Windows终端的编码设置,强制其变为UTF8,甚至不惜更改系统注册表文件,我也试图这么干过,但是我 too young了,搞好了自己编的代码,但是搞崩了所有不是自己的代码,这个划算吗。
经过一番折腾,最终还是回归宽字符,人家既然专门给你准备了适用于你地区的编码方案,为什么自己造自行车。
但是我依然too young了。我太低估windows系统了。
当我用宽字符串打印的时候,一切是和谐而美好的,当我只操作单个宽字符时,一切都变了,又成了乱码,老天,为什么是这样?
于是搜索引擎中打入如下字符串:Msys2 mingw64 widows 宽字符 乱码,然后在搜索结果中找到问题的缘由:
msys2 mingw64环境下使用的C运行时库是windows的msvcrt,而其余的编译器,甚至是windows自家的vs,用的是ucrt。
ucrt是没有上述问题的,是windows解决了各种bug的运行时库。而msvcrt,没有解决这个bug。
看到这里,我的内心是绝望的,原来一个bug经过层层剥离,最终找到的原因是根儿上就有bug,这个bug是无法通过你的代码解决的。
在搜索引擎无法为我解决如何为mingw64更换C运行时库的问题后,我只有两条路:第一忽略他,第二改用其他编译器。
成年人是贪婪的,于是我拥抱了clang64,就这么简单。
相关文献:MinGW-W64使得printf、cout、wprintf、wcout显示出中文的种种
老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>