出现情况
在用notepad++编写helloword程序时,由于将感叹号输成中文的“!”而不是英文的"!",导致运行时出现乱码,结果如下所示。
为什么会出现这个情况,发现在notepad++中选择的字符编码是utf-8。
将其改为ansi试试,乱码的问题就会解决。
什么是字符编码
那什么是字符编码呢?我所理解的字符编码就是“!”这个字符后面藏着它的utf8或者ansi编码,查阅资料后才知道,当我们在一个文件中看到的字符串是系统把内存中的编码信息读取显示出来,当保存文件时系统就会把这个文件以我们所设置的编码方式编码,再放入内存中。例如通信系统中的调制与解调一样,GBK代表AM调制,而utf8代表着FM调制,如果我的发射端是将数据进行AM调幅,当接收端将数据进行FM解调,那解调出的数据肯定会有问题。
因此在cmd控制台出现乱码的原因有一点清晰了,就是我在notepad++中保存的“!”的编码与cmd控制台中需要输出的"!"编码法不一致,导致输出了cmd中默认的编码方式所对应的的汉字“锛”,导致了乱码。因此,先要了解什么是ANSI编码,什么是UTF8编码,什么是GBK编码。
ANSI编码
ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~{} 0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~{} 0xFFFF来编码,即扩展的ASCII编码。ANSI并不是某一种特定的字符编码,而是在不同的系统中,ANSI表示不同的编码。美国人使用的系统中ANSI编码其实是ASCII编码(ASCII编码不能表示汉字,所以汉字为乱码),而我的系统中(“汉字”正常显示)ANSI编码其实是GBK编码。
ASCII码
ASCII码是7位编码,编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。 只支持ASCII码的系统会忽略每个字节的最高位,只认为低7位是有效位。
当时的美国人认为这几位足够表示英文字母了,但是表示中文字符则远远不够,所以有了下一节提到的GBK编码。
GBK编码
GBK编码是国家制定的一个专门用于编码汉字的一套编码方式。GBK编码采用单双字节变长编码,英文使用单字节编码,完全兼容ASCII字符编码,中文部分采用双字节编码。双字节其编码范围从8140至FEFE。
单字节:00000000 - 01111111
双字节:10000001 01000000 - 11111110 11111110
单字节、双字节的区分通过高字节高位区分,单字节高位为0,双字节的高字节高位为1。需要注意的是,GBK编码方式一个汉字是两个字节。
UTF-8编码
UTF-8是一种针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 需要注意的是,UTF-8编码方式一个汉字占3个字节。
如表:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
查看乱码出现的原因
说了这么多,试着看看在UTF8编码下的“!”和GBK编码下的“锛”到底有什么关系。从网上下载一个HxD Hex Editor的软件,这个软件可以把txt文本中的汉字转换成16进制编码。在notepad下以UTF8的编码方式写入“!”,命名为utf8.txt。
新建一个文本设置其编码方式为GBK,输入字符“锛”,命名为gbk.txt。
我们打开HxD Hex.exe软件,把utf8.txt和gbk.txt导入到软件中,查看相应符号的编码。utf8.txt的编码如下图所示,从图中可以看出“!”所对应的十六进制编码为EF BB BF EF BC 81。
gbk.txt的编码如下图所示,从图中可以看出“锛”所对应的十六进制编码为EF BC。
把它们两转为二进制的编码对比看看。
gbk :1110 1111 1011 1100
utf8:1110 1111 1011 1011 1011 1111 1110 1111 1011 1100 1000 0001
GBK显示汉字时只显示2位字节也就是16位二进制数,而且为了标记UTF-8的中文字符,通常会在前面加上EF BF EF的标签,因此在cmd中以GBK方式显示时,去除了UTF-8的标签EF BF EF,就只剩下EF BC 81了,又因为GBK显示一个中文字符需要两个字节的长度,所以就只截取了EF BC两位,而EF BC在GBK中所对应的汉字就是“锛”,为什么会出现乱码的原因应该说明白了。
如何解决乱码
如何解决在cmd当中输入中文乱码的问题,知道其乱码原因之后我们就可以更好的解决这个问题。
方法一:把文本编辑的编码改为ANSI,这样就与cmd的GBK编码对应,显示中文时候就不会出现乱码。但这个方法指标不治本,无法从根本上解决这个问题。
方法二:将cmd的编码类型改为UTF-8,同时notepad++的编写也为UTF-8。这样做的原因是UTF-8可以支持在世界上任何国家任何浏览器支持任何文字,只要对方的编码也是UTF-8,不管他是美国人还是法国人还是印度人,都可以正常的浏览中文。设置方法如下:
打开cmd,输入chcp,就可以查看当前cmd使用的字符编码是什么,936代表着GBK编码。
在cmd中输入chcp 65001,把cmd的字符编码临时改为utf-8编码。
但这样的更改只是一次性的,要想永久更改,需要点击菜单栏右键开“属性”>>“选项”,勾选“丢弃旧的副本”这一项。只有选中了这一项,才能在下一次打开cmd时,保持编码方式为utf-8(65001)。
此时我们重新打开cmd,输入chcp查看目前的编码方式,可以看到此时的编码方式为utf-8(65001)。如果不行就重启一下。
再重新运行一下hello.c看看会不会有乱码,运行结果如下所示。
可以看到中文的“!”可以显示出来了,乱码的问题成功解决!
如果觉得《CMD中文乱码出现的原因及解决办法》对你有帮助,请点赞、收藏,并留下你的观点哦!