C 字符集問題終極分析(可解決亂碼問題) 收藏

2021-05-25 20:11:02 字數 2822 閱讀 2244

系統環境

作業系統                     windows xp

本地字符集(mbcs) gbk

編譯器:                     vc8、vc6、dev-c++(gcc)

實驗字元

『我』

gbk              字元編碼 0xd2ce

unicode     字元編碼 0x6211

『a』

gbk              字元編碼 0x61

unicode     字元編碼 0x0061

a-源**層面

vc8

1.         檔案首兩個位元組為 0xff 0xfe(文字檔案開頭幾個位元組標識了原始檔使用的字符集,開頭為0xff 0xfe表示使用的是unicode字符集),所以原始檔以unicode方式儲存,『我』字元編碼為0x6211,『a』字元編碼為0x0061;

vc6

1.         使用本地字符集gbk儲存源程式,『我』字元編碼為0xd2ce,『a』字元編碼為0x0061;

dev-c++(gcc)

1.         使用本地字符集gbk儲存源程式,『我』字元編碼為0xd2ce,『a』字元編碼為0x0061;

b-可執行程式層面(源程式字符集->可執行程式字符集)

vc8

1.         vc8編譯器預設的程式字符集是本地字符集gbk。

2.         編譯引數#pragma setlocale(loc)告訴編譯器源**字符集為loc,如果不設定則為unicode。

3.         如果字元字面量前有l(l」我」,l」a」),並且設定了編譯引數#pragma setlocale(loc),那麼編譯時將發生loc->unicode字符集的轉換;假如沒有設定則發生源**字符集unicode->unicode的轉換(相當於不發生轉換),』我』的編碼是0x6211,』a』的編碼是0x0061。

4.         如果字元字面量前沒有l,編譯時發生源**字符集unicode->本地字符集gbk編碼的轉換,』我』的編碼是0xd2ce,』a』的編碼是0x61。

vc6

1.         vc6編譯器預設的程式字符集是本地字符集gbk。

2.         編譯引數#pragma setlocale(loc)告訴編譯器源**字符集為loc,如果不設定則為系統預設字符集gbk。

3.         如果字元字面量前有l(l」我」,l」a」),並且設定了編譯引數#pragma setlocale(loc),那麼編譯時將發生loc->unicode字符集的轉換;假如沒有設定則發生源**字符集本地gbk->unicode的轉換,』我』的編碼是0x6211,』a』的編碼是0x0061。

4.         其它情況都不發生任何的字符集編碼轉換(源程式字符集和程式字符集一致),使用本地字符集gbk編碼』,我』的編碼是0xd2ce,』a』的編碼是0x61。

dev-c++(gcc)

1.         dev-c++(gcc)編譯器預設的程式字符集是utf-8。

2.         #pragma setlocale對編譯沒有影響。

3.         如果字元字面量前有l(l」我」,l」a」),那麼編譯時將把字元字面量從配置字元編碼gbk轉換為unicode字元編碼(l開頭的字元字面量都是使用unicode字元編碼),』我』的編碼是0x6211,』a』的編碼是0x0061。注:編譯器引數為-finput-charset=gbk(指定源程式字符集為gbk,如果不指定編譯器預設源程式字符集為utf-8)。

4.         其它情況會發生編譯器配置引數gbk->utf-8字符集的轉換,』我』的編碼是0x9e88e6,』a』的編碼是0x61。這種情況下使用printf列印的時候會出現亂碼,由於本地字符集是gbk,但實際字元編碼是utf-8,解決方法是在程式中把utf-8轉換為本地字符集gbk然後再呼叫printf列印。

5.         在rh linux系統下直接呼叫printf列印不會出問題,因為在該系統下預設字符集是utf-8和編譯器預設字符集一致,所以沒有出現亂碼問題。

c-windowsapi層面

vc8

1.         如果編譯引數配置了unicode則api被解釋為呼叫unicode版本的api(帶標記w的api,這裡w代表unicode字元的含義)。

2.         如果編譯引數沒有配置unicode則api被解釋為呼叫單字元編碼版本的api(帶標記a的api)。

vc6

同vc8。

dev-c++(gcc)

同vc8。

d-雜項&總結

1.         vc中unicode編譯引數只控制windows api的展開,是unicode方式(w標記,這裡w代表unicode字元的含義)還是單字元方式(a標記),其它不做控制。

2.         c++中字元字面量前面如果有標識l,程式執行時這個字元字面量一定unicode字元編碼方式的寬字元(不是其它字元編碼方式)。

3.         c++中如果字元字面量前面沒有標識l,那麼程式執行時這個字元字面量一定是編譯器預設字符集編碼方式(vc中是gbk字符集,』我』的編碼是0xd2ce,』a』的編碼是0x61,dev-c++中是utf-8, 』我』的編碼是0x9e88e6,』a』的編碼是0x61)。

4.         c++中wchar_t,代表寬字元(unicode字元只是寬字元的一種),任何寬字元都可以賦值給wchar_t,包括unicode字元和其它寬字元(比如gbk編碼的漢字字元),所以理論上wchar_t字元僅僅只代表是寬字元,不代表一定是unicode字元(不過一般情況下c++實現都使用unicode字元)。

MYSQL字符集亂碼的解決

命令列下登入mysql 輸入 s 注意到有如下內容 server characterset latin1 db characterset latin1 client characterset latin1 conn.characterset latin1 mysql資料庫預設的字符集是latin1,...

字符集編碼 idea解決亂碼

字元編碼原理 ascii字符集 共收錄128個字元,包括空格 標點符號 數字 大小寫字母和一些不可見字元。由於總共才128個字元,所以可以使用1個位元組來進行編碼,我們看一些字元的編碼方式 l 01001100 十六進製制 0x4c,十進位制 76 m 01001101 十六進製制 0x4d,十進位...

Linux系統字符集亂碼問題

如果你在安裝linux的過程中就選擇了中文,可能可以省去步驟1 2,反之,如果你先安裝了英文環境,而後希望它支援中文,則可以1,2步 1.首先在linux中安裝中文包 安裝簡體中文包 rpm ivh kde i18n chinese x.x.x x.noarch.rpm 其中x.x.x x是版本號 ...