中文亂碼問題分析

2021-10-25 06:03:22 字數 1978 閱讀 5506

在平時處理中文字元時經常會遇到亂碼問題,為了弄清楚其中原因,做了個實驗。

在實驗前需要先了解幾個概念:

1、ansi編碼

ansi不是一種具體的編碼方式,它依賴於當前系統使用的碼表,在命令列中使用chcp命令可以獲取到系統當前使用的碼表。

vs新建的專案預設使用ansi編碼。

2、原始檔編碼

vs新增的檔案預設為ansi編碼,我們可以把原始檔編碼方式改為utf8。但前面提到vs專案預設使用ansi編碼,

所以我們還需要修改專案屬性,以告訴編譯器用utf8編碼來解析原始檔。

專案屬性修改:專案屬性 -> c/c++ -> 所有選項 -> 附加選項 -> 新增"/utf-8"

3、執行時locale屬性

執行時locale指定了實際輸出字元的函式使用的編碼方式。c執行時預設為locale c。

4、vs專案屬性中字符集

字符集屬性並不決定編碼方式,只是通過條件編譯決定了一些通用符號(如tchar等)到底指向unicode版本還是ansi版本。

實驗均建立在原始檔編碼方式和專案使用編碼方式一致前提下:

// setlocale(lc_all, "zh_cn_.utf-8");

// setlocale(lc_all, "chs");

char

*str =

"我";

printf

("%s\n"

, str)

;wchar_t

*wstr = l"我"

;wprintf

(wstr)

;

原始檔

型別locale

記憶體輸出

utf8

char

ce6 88 91

亂碼utf8

wchar_t

c11 62

亂碼utf8

char

utf8

e6 88 91

正常utf8

wcahr_t

utf8

11 62

正常utf8

char

chse6 88 91

亂碼utf8

wchar_t

chs11 62

正常ansi

char

cce d2

正常ansi

wchar_t

c11 62

亂碼ansi

char

utf8

ce d2

亂碼ansi

wchar_t

utf8

11 62

正常ansi

char

chsce d2

正常ansi

wchar_t

chs11 62正常

編碼utf8

unicode

gbk我

e6 88 91

11 62

ce d2

從**可以看出:

1、當用 wchar_t 儲存字串時,實際記憶體中的編碼方式都是 unicode。

2、當用 char 儲存字串時,實際記憶體中的編碼方式和原始檔保持一致。

3、無論記憶體中是什麼編碼方式,輸出既可能亂碼也可能正常。

小結:

編譯器使用專案屬性指定的編碼方式來解析原始檔,並根據儲存字串的型別來決定寫入二進位制檔案的編碼方式,也就是決定了程式執行時記憶體中的編碼方式。

但這不會造成亂碼,造成亂碼的是記憶體到輸出這一過程。

因為記憶體中儲存的肯定是對應字型的其中一種編碼方式,輸出亂碼是因為沒有設定合適的本地編碼方式,使用了錯誤的碼表。

沒查到關於 locale c 和 locale chs 的相關資料,所以沒有得出進一步的結論。

參考:

控制台程式的中文輸出亂碼問題,printf,wprintf與setlocale

Mysql中文亂碼問題分析

1.jsp頁面出問題 2.資料庫連線出問題 jdbc mysql 3.資料庫編碼與客戶端不一致 先檢視下show variables like char 在my.ini中新增 mysql 設定mysql客戶端預設字符集 default character set utf8 mysqld 設定3306...

中文亂碼問題

母頁 tran cel.jsp?p user id p user id p paraxml mytran cel paraxml ie8對window.open二進位製流會遮蔽,用二次請求解決該問題 modify by 20120731。mytran cel paraxml encodeuri my...

中文亂碼問題

url位址中傳遞中文,接收亂碼。修改tomcat的server.xml.在埠號那一項中增加 uriencoding utf 8 connectiontimeout 20000 redirectport 8443 uriencoding utf 8 在form表單中中文亂碼 1.保證你的專案的屬性是u...