- QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
- QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
- QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
網上很多人一碰到編碼問題就無腦的Copy上面3行……
從Qt5開始只剩下setCodecForLocale這一個了,只是影響Qt對toLocal8Bit相關函數的編碼方式
- {
- // Qt默認會使用本機編碼,所以對於中文系統,下面這句設置是多余的
- QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
- QString str1("你好Hello");
- QByteArray bLocal = str1.toLocal8Bit(); // 受setCodecForLocale影響,會轉換為設定的編碼。如果本機不支持指定編碼,則會按toLatin1處理
- QByteArray baLatin1 = str1.toLatin1(); // 不受setCodecForLocale影響,強制轉換為ISO-8859-1編碼
- QByteArray bUtf8 = str1.toUtf8(); // 不受setCodecForLocale影響,強制轉換為UTF-8編碼
- qDebug() << str1; // 正常,Qt會將UTF-16轉換為UTF-8輸出
- qDebug() << baLatin1; // 亂碼,用UTF-8編碼輸出Latin1字節流
- qDebug() << bLocal; // 亂碼,用UTF-8編碼輸出GBK字節流
- qDebug() << bUtf8; // 正常,用UTF-8編碼輸出UTF-8字節流
- QString str2 = QString::fromLocal8Bit(bLocal);
- qDebug() << str2; // 正常,因為上面顯式指定字節流來自本機編碼,而bLocal正是本機編碼GBK
- str2 = QString::fromLatin1(bLocal);
- qDebug() << str2; // 亂碼,bLocal是GBK編碼,但卻指定了以Latin1方式去讀取,肯定會亂碼
- // 字節流來自UTF-8
- str2 = QString::fromUtf8("\xE4\xBD\xA0\xE5\xA5\xBD\x48\x65\x6C\x6C\x6F");
- qDebug() << str2; // 正常
- // Qt默認采用UTF-8處理字符串,所以不用顯式地去調用fromUtf8
- str2 = QString("\xE4\xBD\xA0\xE5\xA5\xBD\x48\x65\x6C\x6C\x6F");
- qDebug() << str2; // 正常
- }
在Qt中,QString會用UTF-16編碼存儲,而qDebug()等I/O函數會以UTF-8編碼處理。
其實轉換后的字節流是正確的,只是顯示時用了和字節流不同的編碼方式處理導致亂碼
所以當要在Qt中輸入輸出非UTF-8字符串時應該先轉換一下
在源碼中要寫入非英文字符的話建議使用轉義的方式,也就是上面“\xE4\xBD...”這種,這也是官方推薦的方式
為了方便將字符串轉換為UTF8轉義字符,寫了一個小工具
http://download.csdn.net/detail/aqtata/5596247
2014-5-6補充:
從vs2010sp1和vs2013開始就已經支持UTF-8的源碼文件了,只用在工程里加入一句"#pragma execution_character_set("UTF-8")"即可。不用再做上面的轉義了。
http://blog.csdn.net/aqtata/article/details/9184741