QT
乱码总结0.Qt乱码产生因素
https://blog.csdn.net/liujiayu2/article/details/103167953
QT
乱码总结1.Unicode 和 UTF-8
https://blog.csdn.net/liujiayu2/article/details/103168020
QT
乱码总结2.gbk和ANSI和gb2312的区别
https://blog.csdn.net/liujiayu2/article/details/103168168
QT
乱码总结3.UNICODE有无BOM
https://blog.csdn.net/liujiayu2/article/details/103168236
QT
乱码总结4.细谈本地编码
https://blog.csdn.net/liujiayu2/article/details/103168249
QT
乱码总结5.万能解决方案
https://blog.csdn.net/liujiayu2/article/details/103168272
QT
乱码总结6.编码测试和总结一
https://blog.csdn.net/liujiayu2/article/details/103168289
QT
乱码总结7.编码测试和总结二
https://blog.csdn.net/liujiayu2/article/details/103168301
QT
乱码总结8.编码测试和总结三
https://blog.csdn.net/liujiayu2/article/details/103168307
QT
乱码总结9.编码测试和总结四
https://blog.csdn.net/liujiayu2/article/details/103168317
QT
乱码总结编码测试工程:
https://download.csdn.net/download/liujiayu2/11987065
/测试环境/
操作系统:WIN7 简体中文版
编译器:VS2010 英文版
QT版本:Qt 4.8.6
/测试编码
我爱中国
ANSI(GBK)编码:CE D2 B0 AE D6 D0 B9 FA
UTF-8编码:E6 88 91 E7 88 B1 E4 B8 AD E5 9B BD
UTF-8编码(bom):EF BB BF E6 88 91 E7 88 B1 E4 B8 AD E5 9B BD
UNICODE编号:\u6211\u7231\u4e2d\u56fd
/
/测试代码/
//#pragma execution_character_set(“AAAAA”)
//#pragma execution_character_set(“gb2312”)
#pragma execution_character_set(“utf-8”)
//#pragma execution_character_set(“big5”)
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle(“CodecStudy_Creator”);
QString str(”
我爱中国
“);
ui->lineEdit->setText(str);
std::string strStdString = str.toStdString();
std::wstring strStdWString = str.toStdWString();
QString hexShow;
for (int i=0; i<strStdString.length(); i++)
{
unsigned char curChar= (unsigned char)strStdString.at(i) ;
char buf[6]={0};
sprintf(buf,”%02x “,curChar);
hexShow += buf;
}
ui->lineEditHex->setText(hexShow);
QString unicodeShow;
QChar qcharArray[20]={0};
for (int i=0;i<str.count();i++)
{
QChar qchar = str.at(i);
qcharArray[i] = qchar;
char buf[7]={0};
const ushort shortChar = qchar.unicode();
sprintf(buf,”\\u%04x “, shortChar);
unicodeShow += buf;
}
ui->lineEditUnicode->setText(unicodeShow);
int a = 0;
}
/
/注意问题/
1.更改编码使用工具NodePad++,更改编码之后,可能需要重写中文字符
2.VS编辑器支持探测当前文件编码,但是不支持实时检测,只能在打开文件一瞬间你检测,
所以当使用NodePad++更改文件编码的时候,推荐不要同时使用VS打开该文件。
3.QString内部采用的是UNICODE。默认编码是Latin-1(又名ISO-8859-1),Latin-1收录语言西欧语言,希腊语言,泰语,阿拉伯语,希伯来语(
没有收录中文简体
)。当字符转化为QString时候都要这样写:QString str = QString::fromXXX(“***”);
不能这样写:QString str = “***”;除非设置了setCodecForString();
因为这样写默认是认为双引号内是Latin-1编码。至于为什么为什么默认是这种编码,可能因为这种编码特殊,使用了单字节内所有空间,其他编码都可以转化为这种编码,不过可能是乱码。
/
测试1:
文件编码:ANSI
使用编码函数或方式:无
测试结果:
总结:
从十六进制可以看出,字符串和文件编码一直都是采用的
gbk
编码。
/
测试2:
文件编码:UTF-8没有BOM
使用编码函数或方式:无
测试结果:
总结:
从十六进制可以看出,字符串和文件编码一直都是采用的
utf-8
编码。
/
测试3:
文件编码:UTF-8有BOM
使用编码函数或方式:无
测试结果:
总结:
从十六进制可以看出,文件编码采用带有
BOM
的
utf-8
编码的时候,
字符串进行编码的时候采用的是本地编码
gbk
而不是
utf-8
编码
。
/
测试4:
文件编码:Latin-1(又名ISO-8859-1)
使用编码函数或方式:无
测试结果:
改变文件编码为Latin-1之后我们就看到编辑器里面就出现了乱码,说明latin-1没有收录中文简体。
不过,我们还是运行一下看看结果。
为什么要进行这样一次测试?
理论上讲如果
Latin-1
有收录中文简体的话,我们不用进行其他乱七八造的设置,只要把文本的编码改为
Latin-1
即可达到中文正常显示的效果。
/
测试5:
查看各种编码的区别:
前四种方式的结果是一样的。
前四种方法 + ANSI文件(或者UNICODE带BOM) = 正确显示
第五种方法 + UNICODE不带BOM文件 = 正确显示
/
测试6:
使用编码函数或方式:
QString
::
fromLocal8Bit
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
QString
::
fromLocal8Bit
+ ANSI文件(或者UNICODE带BOM) = 正确显示
QString
::
fromLocal8Bit
+ UNICODE不带BOM文件 = 乱码
原因分析:
这个很好理解,这个函数名字的意思是 从本地8位编码 到Unicode
中文简体WIndows操作系统本地编码是gb2312啊。这就很好理解上面的情况。
/
测试7:
使用编码函数或方式:
QString
::
fromUtf8
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
QString
::
fromUtf8
+ ANSI文件(或者UNICODE带BOM) = 乱码
QString
::
fromUtf8
+ UNICODE不带BOM文件 = 正确显示
原因分析:
这个很好理解,这个函数名字的意思是 从utf-8编码 到Unicode
/
测试8:
使用编码函数或方式:
QString
::
fromLatin
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
测试结果和什么都不写结果是一样一样的。
原因分析:
这个很好理解,我们之前就说过,QString默认是Latin-1编码
/
测试9:
使用编码函数或方式:
QString
::
fromAscii
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
测试结果令我们大跌眼镜,本以为应该同fromlocal8bit一样。都是从本地编码到UNICO嘛。
看了一下这个函数的注释我们就明白了。
Note that, despite the name, this function actually uses the codec
defined by QTextCodec::setCodecForCStrings() to convert \a str to
Unicode. Depending on the codec, it may not accept valid US-ASCII (ANSI
X3.4-1986) input. If no codec has been set, this function does the same
as fromLatin1().
注释写的很明确,不要从函数名字猜测这个函数是干什么的。这个函数实际是和
QTextCodec::setCodecForCStrings()
搭配使用的,在调用
setCodecForCStrings
之后,
QString
::
fromAscii
使用的就是
setCodecForCStrings
里面的编码。如果不对
setCodecForCStrings
进行设置,
QString
::
fromAscii
就等同与
QString
::
fromLatin1
。简而言之,蛋用没有。
/
测试10:
使用编码函数或方式:
QObject
::
tr
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
这个函数是和
QTextCodec
::
setCodecForTr
联合使用的,单单使用一个是没有效果的。直接使
QObject
::
tr
和只是送
tr
效果是一样的。
/
测试11:
使用编码函数或方式:
QObject
::
trUtf8
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
效果等同与QString::fromUtf8()
/
测试12:
使用编码函数或方式:
#pragma
execution_character_set(
“utf-8”
)
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
使用与不使用完全没啥区别。这预示着,要不本身就是默认这种方式,要不就是这种设置压根没起到作用,为此,我们进行了测试13
/
测试12:
使用编码函数或方式:
QString::fromUtf8 (目的是保证在文件unicode无bom情况下正确显示中文字符)
#pragma
execution_character_set(
“utf-8”
)
#pragma execution_character_set(“gb2312”)
#pragma execution_character_set(“Latin-1”)
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
QString::fromUtf8 固定加上,3个pragma轮流上阵,3中文件编码轮流上阵。共9次测试结果,得到如下结论,#pragma execution_character_set 在本测试环境下是起不到任何作用的。
/
测试13:
使用编码函数或方式:
QString
::
fromStdString
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
加与不加没有区别。
我们看一下Qt源码:
inline
QString
QString
::
fromStdString
(
const
std
::
string
&
s
)
{
return
fromAscii
(
s
.
data
(),
int
(
s
.
size
())); }
结合我们之前对fromAscii这个函数总结这个现象就很好理解了。
/
测试14:
使用编码函数或方式:
QString
::
fromStdWString
文件编码:ANSI、UNICODE无BOM、UNICODE有BOM
测试结果:
QString
str
(
QString
::
fromStdWString
(
”
我爱中国
”
));这样写编译不过。
给他加个L,编译过了,以前一直以为L这个东西是MFC的一个宏。开来C++也支持。
QString
str
(
QString
::
fromStdWString
(L
”
我爱中国
”
));
UNICODE无BOM下乱码,如下图:
ANSI和UNICODE有BOM下正常显示。
我们也看下qt源码
inline
QString
QString
::
fromStdWString
(
const
QStdWString
&
s
)
{
return
fromWCharArray
(
s
.
data
(),
int
(
s
.
size
())); }
不是很常用,也不是很好理解,这里先做一下记录吧,待用到时候仔细研究。