vs2010 qt中文乱码 最终版
2020.11.27?最后終于把這玩意里理解明白了,可能是翻譯引起的理解差異吧。微軟對此做出的解釋:
對于vs編譯器來說,有兩個概念:
源字符集
執行字符集
對于vs2010 sp1-VS2015,引入指令#pragma execution_character_set("utf-8"),這只是將執行字符集設為UTF-8,然而源碼字符集僅僅支持UTF-16 little bom、UTF-16 big、UTF-8 with BOM,你的文件格式UTF-8它就不支持,自己又去轉換了,所以必定亂碼,想不亂碼,必須源碼文件格式保存UTF-8?BOM (VS文件格式中叫 Unicode (UTF-8帶簽名))或者?簡體中文格式 (linux等別的平臺不支持);
);
在VS2015版本(Visual Studio 2015 Update 2)及其之后,微軟放棄了上面的編譯指令,新增編譯選項/utf-8,只需要這一個命令就將源碼字符集和執行文件字符集都指定為UTF-8,所以文件格式并不重要了,一個編譯執行命令,文件編碼格式UTF-8?BOM和UTF-8、?簡體中文格式三個都不會亂碼了,當然優選UTF-8跨平臺換編譯器等都支持?;
//vs2015?updater2以后以下兩個編譯命令等同于這一個命令 /utf-8
/source-charset:utf-8? ? ?源碼字符集設為utf-8
/execution-charset:utf-8? ?執行字符集設為UTF-8
//兩個基礎概念
UTF-8?BOM? ==?Unicode (UTF-8帶簽名)?
UTF-8 ==?Unicode UTF-8無簽名? ? ?//linux等平臺默認支持此。
?
搞清楚以上這幾個概念,再去看微軟官方文檔,便一目了然了。
https://docs.microsoft.com/en-us/cpp/preprocessor/execution-character-set?view=msvc-160
方法如下:
文件編碼格式方法
結論:
1、vs2015?updater2-vs2019,只在vs版本下開發,想保持兼容性,文件編碼格式建議采用UTF-8?BOM最省事,vs商店有插件ForceUTF8 (with BOM);
2、需要跨平臺、庫、算法涉及到跨平臺、linux、換編譯器,文件編碼格式建議UTF-8,只能手動設置;
3、vs2010?sp1-vs2015 ,別想了,只能用UTF-8?BOM!
2020.11.26重新思考后,查看了,微軟官方文檔:
vs編輯器可以區分utf-8和utf-8 bom等,可編譯器不認賬,如果你不是這三個中的一個UTF-16 little bom、UTF-16 big、UTF-8 with BOM它就自做主張按默認處理,那你要么編譯中文亂碼要么qt的ui中文亂碼。
https://docs.microsoft.com/en-us/previous-versions/xwy0e8f2(v=vs.140)?redirectedfrom=MSDN
也可以看看此試驗,作者寫的很詳細:
https://blog.csdn.net/qq_33154343/article/details/78686075?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-1-78686075.nonecase&utm_term=qt%20%E4%B8%AD%E6%96%87%E6%B3%A8%E9%87%8A%E9%80%A0%E6%88%90%E7%BC%96%E8%AF%91%E4%B8%8D%E9%80%9A%E8%BF%87&spm=1000.2123.3001.4430
2020.11.25? 對編碼格式報錯產生疑問,為什么文件編碼格式utf-8 vs2010就報錯?明明QT默認就是這個格式?……
要搞清楚這個問題,先要弄明白編碼。但是編碼問題實在太復雜,這里肯定講不開。
我先找一個例子,比如:"中文" 的 Unicode 碼點/UTF8編碼/GBK 分別是多少。
先去這個網站,輸入 "中文" 查詢對應的 Unicode 碼點/UTF8編碼:
http://www.mytju.com/classcode/tools/encode_utf8.asp
Unicode的碼點分別是(十進制):中(20013),文(25991)。
對應的UTF8編碼分別(16進制): 中(E4B8AD),文(E69687)。
然后再去下面這個網站,輸入 "中文" 查詢對應的 GBK 編碼:
http://www.mytju.com/classcode/tools/encode_gb2312.asp
GBK編碼16進制(GBK內碼)分別是:中(D6D0),文(CEC4)。
現在已經知道了"中文"的UTF8和GBK編碼的具體值。
我們再看看VC2010是怎么處理的。
?
1. 先看 無 BOM 的 UTF8 編碼的代碼 (utf8_no_bom.cpp)
// utf8 no bom // 文件中包含不能在當前代碼頁(936)中表示的字符 #include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xe4 0xb8 0xad 0xe6 }輸出是:0xe4 0xb8 0xad 0xe6。
感覺好像是對的。
但是,先別急:VC編譯時輸出了一條警告信息:
utf8_no_bom.cpp : warning C4819: 該文件包含不能在當前代碼頁(936)中表示的字符。
請將該文件保存為 Unicode 格式以防止數據丟失。
潛臺詞就是,你這個代碼有GBK不能表示的字符,請用Unicode方式保存。
VC根本就沒把 代碼(utf8_no_bom.cpp) 當作UTF8,VC只是把它作為GBK處理罷了。
那為什么又輸出了正確的結果呢?
因為 VC 把 (utf8_no_bom.cpp) 當作 GBK,而編譯時也要轉換為本地編碼(也是GBK)。因此,UTF8編碼的 "中文",被VC當作編碼GBK編碼的 "0xe4 0xb8 0xad 0xe6" 的字符串處理了(肯定不是"中文"含義了)。
?
VC已經不知道 "0xe4 0xb8 0xad 0xe6" 是對應 "中文" 字面值了。
但是在GBK(實際是無BOM的UTF8)轉GBK的過程中,發現了一些UTF8編碼的字符并不是GBK能表達的合理方式,因此就出現了那個C4819編譯警告。
2. 再看帶BOM的UTF8是怎么處理的 (utf8_with_bom.cpp)
?
編譯沒有警告,但是輸出有問題:0xd6 0xd0 0xce 0xc4。
源文件明明是 UTF8 編碼的格式"0xe4 0xb8 0xad 0xe6",
怎么變成了 "0xd6 0xd0 0xce 0xc4" (這個是GBK編碼)?
這就是VC私下干的好事:它自作聰明的將UTF8源代碼轉換為GBK處理了!
VC為何要做這樣蠢事?
原因是為了兼容老的VC版本。
因為以前的VC不能處理UTF8,都是用本地編碼處理的。
3. 在看看真的GBK是怎么處理的 (gbk.cpp)
// gbk #include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xd6 0xd0 0xce 0xc4 }沒有編譯錯誤,輸出也和源代碼一致:"0xd6 0xd0 0xce 0xc4"。
因為源文件就是GBK,cl在編譯時GBK轉化為GBK,沒有改變字符串。
只是,現在很多人不想用GBK了(因為只能在中國地區用,不能表示全球字符)。
------
到這里,可以初步小結一下:
1. VC編輯器和VC編譯器是2個概念,VC編輯器支持UTF8并不能表示VC編譯器也支持UTF8
2. VC編輯器從2008?開始支持帶BOM的UTF8(不帶BOM的暫時沒戲,因為會本地編碼沖突)
3. VC編譯器從2010開始也可以支持UTF8了(雖然支持方式很不優雅)
------
?
繼續前面的測試,
看看VC2010編譯器是怎么支持帶BOM的UTF8的 (utf8_with_bom_2010.cpp)
// utf8 with bom (VC2010), 下面這句是重點! #pragma execution_character_set("utf-8")#include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xe4 0xb8 0xad 0xe6 }沒有編譯錯誤,輸出也和源代碼一致:"0xe4 0xb8 0xad 0xe6"。
UTF8編碼,UTF8輸出。完美!
------
回到 Qt5 的中文輸出問題。
Qt默認支持 VS2010/MinGW/Gcc 等編譯器,而它們現在都已經真正支持UTF8了。
當然,VS2010 對UTF8的支持會入侵代碼(#pragma execution_character_set("utf-8"))。
看看Qt官方論壇別人是怎么說的:
http://qt-project.org/forums/viewthread/17617
?
簡單的說,從Qt5開始,源代碼就是默認UTF8編碼的。
當然,VC2010編輯器對帶BOM的UTF8也是認識,只可惜VC2010編譯器根本不認識!
在繼續看官方論壇的回復:
總結
以上是生活随笔為你收集整理的vs2010 qt中文乱码 最终版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: error: C3861: “pcap_
- 下一篇: 802.1x认证EAP包结构