Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nobodxbodon opened this issue Nov 27, 2021 · 9 comments
Open

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

nobodxbodon opened this issue Nov 27, 2021 · 9 comments

Comments

@nobodxbodon
Copy link
Member

源自 program-in-chinese/team_website#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
Copy link
Member Author

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

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

@HaujetZhao
Copy link

HaujetZhao commented Nov 27, 2021

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

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

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

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

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

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

@tch1121
Copy link

tch1121 commented Dec 28, 2021

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

@HaujetZhao
Copy link

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

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

@nobodxbodon
Copy link
Member Author

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

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

@liuxilu
Copy link

liuxilu commented Jan 4, 2022

  • 这样的技术问题肯定不会是主要问题。
  • “强制GBK”很可疑,现行强标是GB 18030-2005。要强制,也应该是强制支持,而不是强制使用。另外,GB/T 13000 ⇔ ISO 10646 ⇔ Unicode。
  • CSV默认GBK是什么意思,指Excel?测试:Office 2010和2016,打开和新建保存确实如此,而且没看到Excel哪里能改。
  • 测试:Win10文件资源管理器(explorer)修改EXIF,发现编码是UTF-16。
  • Dev-C++默认就是GCC,测试发现汉字路径、汉字文件名均无问题,只是编辑器不支持UTF-8。
  • Windows意外传出GBK不太可能,应该是程序用了ANSI winAPI或没转换UTF-16。
  • 对于已有的程序,可以使用NTLEA或Microsoft AppLocale。Win10还可以尝试“内码”改成UTF-8(上文Excel+CSV应该可用)。
  • 顺便一提,大量存储汉字最好的选择是UTF-16。基本平面汉字 UTF-8 3字节,UTF-16 2字节。

编码问题大多是因为程序未使用Unicode API。作者一般可以修改。技术栈太老太封闭确实困难,但C/C++不在此列。C/C++是最底层的,这也就意味着,它要是不支持Unicode,别的程序凭什么支持。

汉字路径,汉字文件名,Dev-C++ 5.11 (minGW GCC 4.9.2)
UTF-8文件,或GBK文件+编译参数-finput-charset=GBK
在Windows控制台 CP936 & CP65001 都没有乱码

#include <stdio.h>
#include <locale.h>
int main(void) {
	setlocale(LC_ALL, "");
	wprintf(L"你好");
}

@tch1121
Copy link

tch1121 commented Jan 4, 2022

Windows编码问题比较多
ANSI

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

@liuxilu
Copy link

liuxilu commented Jan 5, 2022

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

@farteryhr
Copy link

farteryhr commented Aug 31, 2024

中文编码,史诗巨坑【

当然如果把范围划定为“易用通行的,写代码用用,但别指望它覆盖一切汉字高级需求的”,则直接unicode。

就是要记住,不要认为unicode能完全解决汉字应用的一切需求,不要认为所有字符串数据必须得用unicode。

既然是这个主题,就把我整的大活也发上来【 http://farter.cn/zzdm 字理组字汉字编码,从头开始的汉字编码

普通软件unicode就罢了,如果要做的是处理人名地名古籍等,可能冒出中华文化博大精深的汉字的软件,记得给未来可能使用别的编码方式留门,比如GB13080-2022,比如big5,比如敝编码【

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants