qt5 中文亂碼解決

      網友投稿 1343 2022-05-30

      備注:qt5取消了兩個函數:

      QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

      QTextCodec::setCodecForTr(QTextCodec::codecForLocale());

      一、問題是什么?

      在學習Qt編程的過程中,大多數人都遇到過中文亂碼的問題。總結起來有三類:

      1.?Qt?Creator中顯示的漢字變為亂碼,編輯器上方有“Could?not?decode?"..."?with?"UTF-8"-encoding.?Editing?not?possible.”的錯誤提示。此時,出現亂碼的文檔是不可編輯的。你好中文!”這5個中文字符變成了亂碼

      2.?Qt?Creator中顯示的漢字正常,但編譯的時候會出現“常量中有換行符”等一系列錯誤報警。其實,這也是文字編碼的問題。如下圖所示:

      3.?編譯時未報錯,但生成的程序中文亂碼。如下圖所示:

      其中,第3條是網上提問的最多的,幾乎是所有使用MSVC的初學者都會碰到的問題。很多回答是針對Qt4版本的,Qt5中不可用。

      二、為什么會出現這些問題?

      在解決問題之前,字符編碼知識是必需的。你要知道ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16、BOM是怎么回事。此外,你還要明白源碼字符集、執行字符集是什么。詳細內容可以在網上搜索一下,俯拾即是。

      1.?Qt?Creator的編輯器默認使用UTF-8(代碼頁65001)編碼來讀取文本文件。而Visual?Studio保存文件時默認采用的是本地編碼,對于簡體中文的Windows操作系統,這個編碼就是GB2312(代碼頁936)。如果使用Qt?Creator讀取由Visual?Studio創建的文件,那么編輯器就會以UTF-8編碼格式讀取GB2312編碼格式的文件,出現中文亂碼,因為這兩套編碼系統對漢字編碼是不同的。至于英文部分不會亂碼,是因為UTF-8和GB2312在單字節字符部分是兼容的。

      2.?MSVC在編譯時,會根據源代碼文件有無BOM來定義源碼字符集。如果有BOM,則按BOM解釋識別編碼;如果沒有,則使用本地字符集,對于簡體中文的Windows操作系統就是GB2312。那么,當MSVC遇到一個沒有BOM的UTF-8編碼的文件時,它通常會把文件看作GB2312的來處理。如果文件全是英文沒有問題,但如果包含中文,編譯器就會出現誤讀。這種情況下,Qt?Creator編輯器是正常的。但對于MSVC編譯器,原代碼會被它認識成下圖這個樣子:

      這是我用EverEdit指定本地編碼重讀后的結果,可以看到漢字出錯,末端的引號也沒了。

      在UTF-8中,一個中文字符(漢字或標點符號)占用3個字節,“你好中文!”這5個中文字符共占用15個字節;而在GB2312中,一個中文字符(漢字或標點符號)占用2個字節,這時,MSVC把UTF-8編碼的15個字節加上后面1個字節的英文引號合成16個字節當作8個中文字符處理。之后,MSVC在這一行里直到末尾換行符出現都沒有找到下一個引號,它以為你把字符串在這里敲回車換行了,于是報警稱“常量中有換行符”,并引出一系列的錯誤。

      不過,當以無BOM的UTF-8編碼的字符串正好湊夠偶數個字節時(比如偶數個漢字,或奇數個漢字加奇數個英文字母),編譯器通常不會報警,因為它以為用GB2312編碼讀出的是正確的。

      3.?不管源文件是何種編碼,只要MSVC能夠正確識別,就可以通過編譯。但MSVC的執行字符集默認是本地字符集。對我們來說,它生成的可執行文件中的文字是GB2312編碼的。而生成的Qt程序以UTF-8編碼來識別GB2312編碼的文字,對于“你好中文!”這幾個字符,采用GB2312編碼后再以UFT-8編碼來讀取,就會變成如下的亂碼:

      當以無BOM的UTF-8編碼的字符串正好湊夠偶數個字節時(比如偶數個漢字,或奇數個漢字加奇數個英文字母),反而不會出現亂碼。那是因為,編譯器用GB2312編碼讀出的亂碼本身就是UTF-8編碼的,現在又用UTF-8解讀,自然就正確了。這純粹是歪打正著。

      三、怎么解決這些問題?

      首先,你要確定采用哪種源碼字符集。你有兩個選擇:

      1.?采用本地編碼字符集(不推薦,跨平臺時會比較麻煩,但在Visual?Studio環境下配合Add-in工具編程比較方便);

      2.?采用UTF-8編碼字符集(推薦,適合跨平臺)。

      1?“采用本地編碼字符集”方案,解決方法如下:

      首先,要把項目中所有的頭文件和源文件全都轉換成GB2312編碼保存。

      1.?第1個問題:在Qt?Creator中打開項目,點擊左側工具欄“項目”,在“編輯器”選項卡中把“默認編碼”改成“GB2312”。如下圖所示:

      qt5 中文亂碼解決

      話說回來,既然選擇本地字符集,大致上是放棄跨平臺了。與其用輕量級的Qt?Creator,不如用Visual?Studio作開發環境更好。

      2.?第2個問題:“常量中有換行符”等一系列報警已不存在了。

      3.?第3個問題:在字符串常量上加QStringLiteral宏或QString::fromLocal8Bit函數,如:

      QString?str?=?"你好中文!";

      改為:

      QString?str?=?QStringLiteral("你好中文!");

      或者:

      QString?str?=?QString::fromLocal8Bit("你好中文!");

      不過,在這兩種形式下,你都無法用tr方法來創建翻譯了。

      2?“采用UTF-8編碼字符集”方案,解決方法如下:

      首先,要把項目中所有的頭文件和源文件全都轉換成UTF-8+BOM編碼保存。

      1.?第1個問題不存在了。

      2.?第2個問題也不存在了。

      3.?第3個問題,你也可以用上個方案中的方法來解決,但有更好的方法。那就是要用到中文字符的頭文件和源文件開頭加上MSVC的一個宏:

      #if?_MSC_VER?>=?1600

      #pragma?execution_character_set("utf-8")

      #endif

      這個宏告訴MSVC,執行字符集是UTF-8編碼的,別瞎整成GB2312的!還有個好處,就是能用tr包中文,方便日后的翻譯。最終效果如下:

      FROM: ?http://liuweilhy.blog.163.com/blog/static/11405670201510901627229/

      C++ Qt

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:[經驗]解決使用opencv 高分辨率下的攝像頭卡頓不流暢
      下一篇:Flink入門學習筆記
      相關文章
      亚洲AV无码专区国产乱码4SE | 亚洲AV无码专区亚洲AV伊甸园| 色欲aⅴ亚洲情无码AV蜜桃| 亚洲白色白色在线播放| 亚洲精品中文字幕无码蜜桃| 亚洲综合色在线观看亚洲| 亚洲精品国产自在久久| 亚洲av无码成人精品区在线播放| 亚洲av无码专区亚洲av不卡| 亚洲av无码兔费综合| 久久亚洲精品无码gv| 老子影院午夜伦不卡亚洲| 国产成人人综合亚洲欧美丁香花| 亚洲av乱码中文一区二区三区| 亚洲AV无码专区在线观看成人 | 老子影院午夜伦不卡亚洲| 四虎亚洲国产成人久久精品| 亚洲а∨天堂久久精品| 亚洲国产一成久久精品国产成人综合| 亚洲av无码国产精品色在线看不卡| 亚洲 无码 在线 专区| 亚洲精品成人在线| 亚洲精品老司机在线观看| 久久久精品国产亚洲成人满18免费网站| 亚洲国产精品成人| 亚洲人成网77777亚洲色 | 国产亚洲精品成人AA片新蒲金 | 一本色道久久综合亚洲精品蜜桃冫 | 国产精品亚洲综合久久| 亚洲最大天堂无码精品区| 亚洲国产精品无码中文lv| 国产精品久久久久久亚洲小说| www国产亚洲精品久久久| 亚洲区小说区图片区| 亚洲精品美女久久777777| 亚洲国产成人久久精品影视| 亚洲日产2021三区| 亚洲真人无码永久在线观看| 国产亚洲高清在线精品不卡| 久久激情亚洲精品无码?V| 亚洲精品无码av人在线观看|