在windows下的记事本中输入“我a”,分别以ANSI、Unicode、UTF-8保存,然后用16进制打开:
ANSI:ced2 61
Unicode:fffe 1162 6100 (fffe是记事本用于标识是unicode编码的标识符)
UTF-8:efbb bfe6 8891 61 (efbb bf是记事本用于标识是utf-8编码的标识符)
ANSI编码(默认):英文1个字节,中文2个字节,即一个字节最高为1时,与后一个字节合并组成双字节,为一个字符,否则为ASCII字符。
Unicode:无论中英文,每个都是2个字节。
UTF-8:英文1个字节,中文3个字节。
///
Windows中的Qt Creator的编辑器本身使用的是操作系统默认的编码,与记事本一样也是ANSI编码,可以用16进制编译器打开源文件比对中文字符对应的二进制数据。
上面QString str("我a");
“我a”实际的16进制为:ced261,ced2是‘我’,61是'a'
而QString内部是以Unicode形式保存的。
QString得到的是由编译器送给的数据"ced261",显然在保存成unicode前,必须进行编码转换。
而Qt对常量字符串(双引号内的字符串)默认是认为Latin-1编码的,该编码用于欧洲文字(最高位为1时是比如希腊字母等之类的),都是以1个字节表示的,所以在对”我a“,保存进QString时,认为是3个字符ce 、d2和61。此时QString的size是3,内部则为0x00ce、0x00d2、0x0061 这3个字符。
要正确保存成Unicode,则需要制定对于常量字符串的编码。通过QTextCodec::setCodecForCStrings(QTextCodec *c)来设定。
c代表常量字符串的编码,默认就是Latin-1。
当c为QTextCodec::codecForLocale()时,就是当前时区的编码(一般操作系统指定)。
所以在main函数开始出添加语句QTextCodec::setCodecForCStrings( QTextCodec::codecForLocale()); 后就可以使QString转换时识别文本编辑器的编码,而不是Latin-1。
可以发现,此时QString内size为2,第一个字符16进制为6211与记事本中保存”我“的unicode一致。
另外可以看到,QChar赋值使用单引号时,仍旧没有正确的进行转换,导致在QString append ’我'这个QChar后,最后一个’我‘,仍旧无法正常显示。