问题:
Qt代码 cpp
或者h文件从windows传到Ubuntu后会显示乱码
原因:
Ubuntu环境设置默认是utf-8
,Windows环境设置默认是GBK
,编码方式不同,因此,相同的文件在不同环境下会出现乱码现象
基于此,引发出一系列关于编码的思考~~
编码:
信息以二进制数表示,编码是按照某种规则将字符存储为二进制数;解码是将二进制数解析并显示出来,在解码过程中,若使用错误的解码规则,就会导致乱码。
字符集:
一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各个国家文字、标点符号、图形符号、数字等,常见的字符集有:ASCII字符集、GB2312
字符集、Unicode字符集等。
字符编码:
一套法则,符号集合与数字系统之间建立关系,
对应的编码方式有:ASCII码编码、GBK
编码、UTF-8编码、UTF-16编码等
Unicode是字符集,UTF-8
、UTF-16
、UTF-32
是三种字符编码方案
ASCII编码:
共128字符,使用7位或8位二进制数组合来表示可能128或256种字符。
GBK
编码:
国标、汉字内码扩展规范,在windows下使用,中文编码。
Unicode字符集:
统一码、为每种语言的每个字符设置了统一并且唯一的二进制编码,可以跨语言、跨平台进行文本转换。
UTF-8
编码:
针对Unicode的一种可变长度字符编码。可以用来表示Unicode标准中的任何字符。
UTF-8
带BOM
与不带BOM
:
BOM
:Byte Order Mark 字节序标记
BOM是专门为UTF-16与UTF-32准备,用来标记字节序,以UTF-16来举例,以两个字节为编码单位,在解释一个UTF-16文本之前,首先要弄清楚每个编码单元的字节序
例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流"594E",那么这是“奎”还是“乙”?
Unicode规范中推荐的标记字节顺序的方法是带BOM:
BOM:在UCS编码中有一个叫做“Zero width No-Break space”的字符(零宽度无间断空间),编码为FEFF。FEFF为不可见字符 ,所以不应该出现在实际传输中。
UCS规范建议在传输字节流之前,先传输ZERO WIDTH No-BREAK SPACE 。如果接收者接收到FEFF,就表明字节流是Big-Endian;如果收到FFFE,就表明字节流是Little-Endian
因此字符“ZERO WIDTH NO-BREAK SPACE”又被称为BOM。
UTF-8编码是以1个字节为单位进行处理的,不会受CPU大小端的影响;需要考虑下一位时就地址 + 1。UTF-8一般最好不要带BOM。
UTF-16、UTF-32是以2个字节和4个字节为单位进行处理的,即1次读取2个字节或4个字节,这样一来,在存储和网络传输时就要考虑1个单位内2个字节或4个字节之间顺序的问题
UTF-8如何去除BOM
Linux:A:
1)vim打开文件
2)执行:set nobomb
3)保存:wq
B:dos2unix filename
将windows格式文件转为Unix、Linux格式文件。该命令不仅可将windows文件的换行符\r\n转为Unix、Linux文件的换行符\n,还可以将UTF-8 Unicode (with BOM)转换为UTF-8 Unicode.
1个UTF-8 Unicode (with BOM)文件中包含两个<U+FEFF>,这是无论使用方法A还是方法B,都要执行两次才能将<U+FEFF>完全去除!!!
Windows下,使用NotePad++打开这个文件,然后选择“编码”,再选择“以UTF-8无BOM格式编码”,最后重新保存文件即可!