QT乱码总结6.编码测试和总结一
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())); }
不是很常用,也不是很好理解,這里先做一下記錄吧,待用到時候仔細研究。
?
總結
以上是生活随笔為你收集整理的QT乱码总结6.编码测试和总结一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT乱码总结5.万能解决方案
- 下一篇: QT乱码总结7.编码测试和总结二