一、文本编码和代码页
文本编码是指编写文本所使用的编码字符集。各个国家、地区为了用计算机记录并显示自己的字符,都在ASCII编码方案的基础上,设计了各自的编码方案。所有这些各个国家和地区所独立制定的既兼容ASCII编码又互相之间不完全兼容的字符编码,微软统称为ANSI编码。
代码页是字符集在计算机中的具体编码实现,可以体现为从字符映射到单字节值或多字节值的一张表格。代码页主要用于具体实现各编码方案中的字符在计算机系统中的物理存储和显示。
更多详情见:https://zhuanlan.zhihu.com/p/27136737
使用一些文本编辑器(比如Notepad++、VSCode等)打开一个文档,可以看到其所使用的编码字符集,如下图:
使用chcp
命令可以查看当前CMD界面的活动代码页,如下图:
二、为什么会中文显示乱码
先来做一个小测试:我们用3种编码字符集写了内容相同的bat脚本,然后在CMD界面在不同的代码页下去运行它们。如下图:
可以看到,hello world
总是能正常显示,而你好,世界
只在部分情况(GB2312编码和936代码页组合、UTF-8编码和65001代码页组合)下显示正常。(ANSI编码不是指某种具体的编码,它与系统设置中的“区域”设置有关,在“中国”区域等同于中文编码,这里不做讨论)
有了上面的小测试及第一部分文本编码和代码页的介绍,我们可以得出结论:文本编码和代码页不匹配导致了中文显示乱码。代码编写默认使用UTF-8编码,而中国区的CMD界面默认代码页是936,两者默认不匹配会导致中文显示乱码。这就相当于,编写要显示的文字时用了规则A去存储,然后真正显示时用了规则B去解析,暗号没对上当然会出现乱码。事实上,不只中文会乱码,韩文、日文等也可能出现乱码,应该只有英文不会出现乱码(各种编码方案都兼容ASCII编码字符)。
三、中文显示乱码的解决方案
- 中文显示场景通常较多的是打印提示信息或者日志信息,在可能的情况下,用英文替代中文。
- 在CMD界面用
chcp
命令临时切换代码页,使之与要显示的中文的编码方式匹配。 - 在注册表中给
计算机\HKEY_CURRENT_USER\Console
项下面某个具体的终端工具新建一个DWORD值,名称为CodePage
,数据为65001
,使其默认代码页为65001,与代码编写的默认编码匹配。如下图:
- 在注册表中给
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor
项新建一个字符串值,名称为AutoRun
,数据为chcp 65001
,这会影响所有的终端工具(比如cmd、powershell和cmder等)。如下图:
推荐解决方案1、2、3联合使用,不推荐方案4(该方案看着和方案3差不多,实际可能导致有些项目编译不过,还很难排查出问题,笔者就遇到过)。