overview icon indicating copy to clipboard operation
overview copied to clipboard

编码规范不统一的现状与解决方案

Open nobodxbodon opened this issue 2 years ago • 8 comments

源自 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++ 编译器也无法正常工作。

nobodxbodon avatar Nov 27 '21 16:11 nobodxbodon

@HaujetZhao 早先遇到过一个编码问题,见前文:都市传说: "部分"中文出现乱码

不妨探讨一下各种原因和可能的解决方案。比如,是由中文字符串还是中文命名标识符引起的、是否需要控制台编码设置,以及如果无法规避的话是否可以开发相关工具链解决(编辑器、运行环境等等)。

nobodxbodon avatar Nov 27 '21 19:11 nobodxbodon

无法解决,这是历史问题。在文件中使用中文变量命名,没问题。

但是输出中文字符串、使用中文路径、读取文件有含有中文的元数据,就有问题。

有绕弯子的办法,使用第三方库进行编码转换。exiftool exiv2 开发者都搞了,说太难,搞不动。

编译器是要把常量处理成字节码的,如何处理,已经由源码编码决定了,还能有什么办法?只能搞中间拓展层。有能力搞、搞得出来、搞出来各个系统都能用、搞了别人愿意用,这都是难题。

计算机世界本就是不完美的,只能接受这个设定。

C 和 C++ 都是底层最接近汇编、硬件的,历史包袱很重,对他们不太期待完善的中文处理了。我目前也就敢在 Python 这样的解释语言中肆意用中文。

HaujetZhao avatar Nov 27 '21 22:11 HaujetZhao

之前ffmpeg打印带有中文的元数据内容也是乱码,后来不知道什么版本起在 chcp 936chcp 65001 都能正常显示中文 所以我认为编码问题是能解决的

tch1121 avatar Dec 28 '21 15:12 tch1121

之前ffmpeg打印带有中文的元数据内容也是乱码,后来不知道什么版本起在 chcp 936chcp 65001 都能正常显示中文 所以我认为编码问题是能解决的

其时间和精力成本无法普及到大多数程序员所写的程序上。

HaujetZhao avatar Dec 28 '21 15:12 HaujetZhao

个人认为,技术终归是为需求服务而且不断进步的。用中文的多了,迟早会有辅助或者解决方案出现。IDE的中文补全辅助插件就是个最近的例子。

想当初,上世纪七十年代还有专家认为 ”汉字无法进入电脑“ 呢。

nobodxbodon avatar Dec 28 '21 22:12 nobodxbodon

  • 杩欐牱鐨勬妧鏈棶棰樿偗瀹氫笉浼氭槸涓昏闂銆?/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"浣犲ソ");
}

liuxilu avatar Jan 04 '22 13:01 liuxilu

Windows编码问题比较多 ANSI

// nodejs
spawnSync('pwsh', ['-c', 'Get-Clipboard'])

tch1121 avatar Jan 04 '22 14:01 tch1121

require('child_process').spawnSync('powershell', ['-c', '[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;Get-Clipboard'], { encoding: 'UTF-8' } )

liuxilu avatar Jan 05 '22 08:01 liuxilu