overview
overview copied to clipboard
编码规范不统一的现状与解决方案
源自 https://github.com/program-in-chinese/team_website/issues/27 :
阻碍中文编程发展的,主要是编码规范不统一的问题。
国内 Windows 系统是强制 gbk 编码(国家强制要求),国际通用是 UTF-8 编码。Linux 和 MacOS 是 UTF-8 编码。
即使国家取消强制 GBK 编码,Windows 也会因沉重的历史兼容性包袱不能轻易改成 UTF-8,因为那样会使许多旧软件出现问题。
用 utf-8 编码编写的 c/c++ 源码,进行编译后,在 Linux 控制台输出正常。但同一份源码,在国内 Windows 编译后,控制台的输出中文就是乱码。
如果用 GBK 编码保存源码,在国内 win 输出可以正常,但同一份源码在 Linux 下编译后, Linux 控制台输出中文就是乱码。
总之,由于两种编码冲突,输出中文乱码现象很严重,难以保证同一份源代码在所有系统上都输出正确的中文,甚至是不能识别正确的中文输入、中文路径。
一些文件元数据存储文字也跟随 win 系统,windows 使用 gbk,例如 CSV 的默认格式就是 GBK,如果读取 UTF-8 的 CSV 文件,就会有乱码。
在国内 Windows 系统上为照片修改元数据、标签,就是以 GBK 储存,许多国际软件(例如 exiftool exiv2)都只做了 utf-8 支持,读取的结果就出现了乱码。
另外,有的软件读取目录,使用 UTF-8 编码,但 Windows 给它传递 GBK 编码,结果就找不到文件。典型:pngquant
如果在源文件名中使用了中文,GCC 的 C++ 编译器也无法正常工作。
@HaujetZhao 早先遇到过一个编码问题,见前文:都市传说: "部分"中文出现乱码
不妨探讨一下各种原因和可能的解决方案。比如,是由中文字符串还是中文命名标识符引起的、是否需要控制台编码设置,以及如果无法规避的话是否可以开发相关工具链解决(编辑器、运行环境等等)。
无法解决,这是历史问题。在文件中使用中文变量命名,没问题。
但是输出中文字符串、使用中文路径、读取文件有含有中文的元数据,就有问题。
有绕弯子的办法,使用第三方库进行编码转换。exiftool exiv2 开发者都搞了,说太难,搞不动。
编译器是要把常量处理成字节码的,如何处理,已经由源码编码决定了,还能有什么办法?只能搞中间拓展层。有能力搞、搞得出来、搞出来各个系统都能用、搞了别人愿意用,这都是难题。
计算机世界本就是不完美的,只能接受这个设定。
C 和 C++ 都是底层最接近汇编、硬件的,历史包袱很重,对他们不太期待完善的中文处理了。我目前也就敢在 Python 这样的解释语言中肆意用中文。
之前ffmpeg打印带有中文的元数据内容也是乱码,后来不知道什么版本起在 chcp 936
和 chcp 65001
都能正常显示中文
所以我认为编码问题是能解决的
之前ffmpeg打印带有中文的元数据内容也是乱码,后来不知道什么版本起在
chcp 936
和chcp 65001
都能正常显示中文 所以我认为编码问题是能解决的
其时间和精力成本无法普及到大多数程序员所写的程序上。
- 杩欐牱鐨勬妧鏈棶棰樿偗瀹氫笉浼氭槸涓昏闂銆?/li>
- 鈥滃己鍒禛BK鈥濆緢鍙枒锛岀幇琛屽己鏍囨槸GB 18030-2005銆傝寮哄埗锛屼篃搴旇鏄己鍒舵敮鎸侊紝鑰屼笉鏄己鍒朵娇鐢ㄣ€傚彟澶栵紝GB/T 13000 鈬?ISO 10646 鈬?Unicode銆?/li>
- CSV榛樿GBK鏄粈涔堟剰鎬濓紝鎸嘐xcel锛熸祴璇曪細Office 2010鍜?016锛屾墦寮€鍜屾柊寤轰繚瀛樼‘瀹炲姝わ紝鑰屼笖娌$湅鍒癊xcel鍝噷鑳芥敼銆?/li>
- 娴嬭瘯锛歐in10鏂囦欢璧勬簮绠$悊鍣紙explorer锛変慨鏀笶XIF锛屽彂鐜扮紪鐮佹槸UTF-16銆?/li>
- Dev-C++榛樿灏辨槸GCC锛屾祴璇曞彂鐜版眽瀛楄矾寰勩€佹眽瀛楁枃浠跺悕鍧囨棤闂锛屽彧鏄紪杈戝櫒涓嶆敮鎸乁TF-8銆?/li>
- Windows鎰忓浼犲嚭GBK涓嶅お鍙兘锛屽簲璇ユ槸绋嬪簭鐢ㄤ簡ANSI winAPI鎴栨病杞崲UTF-16銆?/li>
- 瀵逛簬宸叉湁鐨勭▼搴忥紝鍙互浣跨敤NTLEA鎴朚icrosoft AppLocale銆俉in10杩樺彲浠ュ皾璇?a href="https://zhuanlan.zhihu.com/p/153219931">鈥滃唴鐮佲€濇敼鎴怳TF-8锛堜笂鏂嘐xcel+CSV搴旇鍙敤锛夈€?/li>
- 椤轰究涓€鎻愶紝澶ч噺瀛樺偍姹夊瓧鏈€濂界殑閫夋嫨鏄疷TF-16銆傚熀鏈钩闈㈡眽瀛?UTF-8 3瀛楄妭锛孶TF-16 2瀛楄妭銆?/li>
缂栫爜闂澶у鏄洜涓虹▼搴忔湭浣跨敤Unicode API銆備綔鑰呬竴鑸彲浠ヤ慨鏀广€傛妧鏈爤澶€佸お灏侀棴纭疄鍥伴毦锛屼絾C/C++涓嶅湪姝ゅ垪銆侰/C++鏄渶搴曞眰鐨勶紝杩欎篃灏辨剰鍛崇潃锛屽畠瑕佹槸涓嶆敮鎸乁nicode锛屽埆鐨勭▼搴忓嚟浠€涔堟敮鎸併€?/p>
姹夊瓧璺緞锛屾眽瀛楁枃浠跺悕锛孌ev-C++ 5.11 (minGW GCC 4.9.2)
UTF-8鏂囦欢锛屾垨GBK鏂囦欢+缂栬瘧鍙傛暟-finput-charset=GBK
鍦╓indows鎺у埗鍙?CP936 & CP65001 閮芥病鏈変贡鐮?/p>
#include <stdio.h>
#include <locale.h>
int main(void) {
setlocale(LC_ALL, "");
wprintf(L"浣犲ソ");
}
Windows编码问题比较多 ANSI
// nodejs
spawnSync('pwsh', ['-c', 'Get-Clipboard'])
require('child_process').spawnSync('powershell', ['-c', '[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;Get-Clipboard'], { encoding: 'UTF-8' } )