編譯器對原始檔編碼的處理

2021-06-17 16:41:57 字數 1820 閱讀 2798

"漢字"

gbk編碼:ba ba , d7 d6

utf-8編碼:e6 b1 89, e5 ad 97

utf-16be編碼:6c 49, 5b 57

兩種常用編譯器gcc,cl中對unicode字面值的實現:

gcc中跟編碼方式轉換有關的三個編譯選項:

有了以上鋪墊,下面兩條語句的意義就很清楚了:

[cpp]view plain

copy

char

cstr = 

"漢字"

; //將"漢字"由-finput-charset指定的編碼方式轉換成由-fexec-charset指定的編碼方式。

wchar_t

wstr = l

"漢字"

; //將"漢字"由-finput-charset指定的編碼方式轉換成由-fwide-exec-charset指定的編碼方式。

注1:gcc在4.4.0版本以前存在bug,不能編譯帶bom的utf-8原始檔。參見

注2:qt自帶的mingw gcc 4.4.0貌似有bug,不能支援-finput-charset選項;tdm gcc 4.5.1則沒有這個問題。

注3:即便tdm gcc 也不能支援utf-16,無論be或者le。症狀是好像只要包含了標頭檔案--無論是標準庫的標頭檔案還是qt的標頭檔案,就無法編譯通過,不包含標頭檔案則是可以編譯通過的。

cl 沒有提供類似gcc指定編碼方式的編譯選項,只能使用預設值或靠自動識別:

再看同樣的語句在 cl 下的行為:

對於原始檔的編碼方式為utf-16be,utf-16le, utf-8(帶bom):

[cpp]view plain

copy

char

cstr = 

"漢字"

; //將原始檔中的"漢字"從當前編碼方式轉換成ansi編碼方式,即gbk。

wchar_t

wstr = l

"漢字"

; //將原始檔中的"漢字"從當前編碼方式轉換成utf-16編碼方式。

對於其他編碼方式的原始檔(包括無bom的utf-8),實際上會被當做ansi編碼,即gbk:

[cpp]view plain

copy

char

cstr = 

"漢字"

; //認為已經是ansi編碼了,故沒有轉換發生,cstr中依舊是"漢字"的原始編碼。例如,如果原始檔的編碼方式為無bom的utf-8,則cstr中依舊是"漢字"的utf-8編碼。

wchar_t

wstr = l

"漢字"

; //無論原始檔採用何種編碼方式,都將"漢字"當做ansi編碼,轉換成utf-16編碼。這樣硬轉的結果當然是除了當前是gbk編碼時能正常轉換,其餘各種編碼方式得到的只能是亂碼一堆。

有關cl對unicode的支援請參考:

c++1x

面對如此混亂的局面,c++1x提供了更多字串字面值表示法:

"string of char characters in some implementation defined encoding" - char

u8"string of utf8 chars" - char

u"string of utf16 chars" - char16_t

u"string of utf32 chars" - char32_t

l"string of wchar_t in some implementation defined encoding" - wchar_t

原始檔在編譯器中的處理過程

預處理 1.只進行預處理操作 gcc e demo.c demo2.i 大於號的作用是把進行預處理操作後生成的.i檔案放到大於號後面的檔案裡面,稱作重定向。經過預處理之後的檔案字尾名為.i 2.預處理做的事情包括 標頭檔案展開 巨集替換 條件編譯 條件編譯在實際應用中非常多,通過條件編譯可以選擇編譯...

撥開字元編碼的迷霧 編譯器如何處理檔案編碼

使用visual studio建立的c 工程可以在工程屬性配置屬性 常規中配置字符集 使用unicode字符集 預設 使用多位元組字符集。這個設定項不對字元編碼產生直接的影響 注意這裡的 直接 二字,第3節會說到 只會在工程屬性配置屬性 c c 預處理器加入相應的巨集 使用unicode字符集 un...

撥開字元編碼的迷霧 編譯器如何處理檔案編碼

使用visual studio建立的c 工程可以在工程屬性配置屬性 常規中配置字符集 使用unicode字符集 預設 使用多位元組字符集。這個設定項不對字元編碼產生直接的影響 注意這裡的 直接 二字,第3節會說到 只會在工程屬性配置屬性 c c 預處理器加入相應的巨集 使用unicode字符集 un...