尊重作者,支援原創,如需轉載,請附上原位址: https://blog.csdn.net/libaineu2004/article/details/19245205 這篇文章有點長,内容有點多,如果時間急迫,可以直接翻頁去末尾看結論。紅色字型加粗的。(#^.^#)
一、Qt Creator環境設定
1、cpp或h檔案從window上傳到Ubuntu後會顯示亂碼,原因是因為ubuntu環境設定預設是utf-8,Windows預設都是GBK.
我們使用的Windows系統本地字元集編碼為GBK。
2、Windows環境下,Qt Creator,菜單->工具->選項->文本編輯器->行為->檔案編碼->預設編碼,常用的選項有以下幾個:
System(簡體中文windows系統預設指的是GBK編碼)
GBK/windows-936-2000/CP936/MS936/windows-936
UTF-8
二、編碼知識科普
Qt常見的兩種編碼是:UTF-8和GBK
★UTF-8:Unicode TransformationFormat-8bit,允許含BOM,但通常不含BOM。是用以解決國際上字元的一種多位元組編碼,它對英文使用8位(即一個位元組),中文使用24為(三個位元組)來編碼。UTF-8包含全世界所有國家需要用到的字元,是國際編碼,通用性強。UTF-8編碼的文字可以在各國支援UTF8字元集的浏覽器上顯示。如果是UTF8編碼,則在外國人的英文IE上也能顯示中文,他們無需下載下傳IE的中文語言支援包。
★GBK是國家标準GB2312基礎上擴容後相容GB2312的标準。GBK的文字編碼是用雙位元組來表示的,即不論中、英文字元均使用雙位元組來表示,為了區分中文,将其最高位都設定成1。GBK包含全部中文字元,是國家編碼,通用性比UTF8差,不過UTF8占用的資料庫比GBD大。GBK是GB2312的擴充,除了相容GB2312外,它還能顯示繁體中文,還有日文的假名。
★GBK、GB2312等與UTF8之間都必須通過Unicode編碼才能互相轉換:
GBK、GB2312--Unicode--UTF8
UTF8--Unicode--GBK、GB2312
★在簡體中文windows系統下,ANSI編碼代表GBK/GB2312編碼,ANSI通常使用0x80~0xFF範圍的2個位元組來表示1個中文字元。0x00~0x7F之間的字元,依舊是1個位元組代表1個字元。Unicode(UTF-16)編碼則所有字元都用2個位元組表示。
三、編碼轉換
Windows自帶的記事本,無法檢視UTF-8編碼的檔案到底有無BOM,需要使用其他檔案編輯器,比如EditPlus或者SublimeText。
UTF-8與ANSI(即GBK)的互轉,可以使用EditPlus工具"檔案另存為"或者Encodersoft編碼轉換工具對.cpp和.h源檔案文本進行批量轉換.
四、QString顯示中文亂碼的原因
我們使用的Windows系統本地字元編碼(Local字元集)為GBK。編譯器分析出源檔案字元編碼之後,會進行解碼再編碼,将源字元集轉碼成執行字元集。執行字元集一般預設為使用本地字元編碼(Local字元集)。
Qt5可以設定Local字元集,GBK/UTF-8
QTextCodec *codec = QTextCodec::codecForName("UTF-8");//或者"GBK",不分大小寫
QTextCodec::setCodecForLocale(codec);
Qt5中QString内部采用unicode字元集,utf-16編碼。構造函數QString::QString(const char *str)預設使用fromUtf8(),将str所指的執行字元集從utf-8轉碼成utf-16。
由上面fromUtf8()可知,QString需要執行字元集編碼為utf-8,然後以utf-8進行解碼,再編碼為utf-16才能獲得正确的字元編碼。顯示中文亂碼的原因其實就是QString轉碼方式與執行字元集不一緻。(比如,源字元集為本地字元集GBK編碼,QString以utf-8的方式進行解碼,會導緻獲得錯誤的二進制編碼,再将錯誤二進制轉為utf-16就會出現亂碼。)
五、Qt編碼指定
Qt需要在main()函數指定使用的字元編碼:
#include <QTextCodec>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//設定中文字型
a.setFont(QFont("Microsoft Yahei", 9));
//設定中文編碼
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
#if _MSC_VER
QTextCodec *codec = QTextCodec::codecForName("GBK");
#else
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
#endif
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
#else
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
#endif
return a.exec();
}
這裡隻列舉大家最常用的3個編譯器(微軟VC++的cl編譯器,Mingw中的g++,Linux下的g++),源代碼分别采用GBK和無BOM的UTF-8以及有BOM的UTF-8這3種編碼進行儲存,發生的現象如下表所示。
情況1:指的是Local字元集為GBK
情況2:指的是Local字元集為UTF-8
源代碼的編碼
編譯器
顯示正常
顯示亂碼
GBK
win vs cl
情況1
情況2
win mingw-g++
linux g++
UTF-8(無BOM)
編譯失敗
error C2001: 常量中有換行符
UTF-8(有BOM)
情況2(有#pragma預處理)
情況2(沒有#pragma預處理)
如果您使用的是Visual C++編譯器,則預設情況下不會将您的源代碼視為utf-8編碼。除非有BOM,否則它将使用您目前的代碼頁進行解釋。就是說,當使用Visual C++編譯程式的時候,它會分析源檔案采用何種編碼,有BOM辨別符則可以正确識别其編碼是UTF-8,若沒有BOM辨別符則認為其使用本地字元集編碼(Local字元集)。Local字元集是什麼?取決于你的設定QTextCodec *codec = QTextCodec::codecForName(???);
如果源檔案是UTF-8+BOM的編碼方式,還需要在頭檔案加入
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif
或者添加QMAKE_CXXFLAGS += /utf-8到您的.pro檔案中。
如果源檔案是UTF-8+無BOM的編碼方式,則一定不能加#pragma execution_character_set(“utf-8”),不然會産生亂碼。