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

2021-08-07 16:21:33 字數 2070 閱讀 1028

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

使用unicode字符集 --> _unicode和unicode巨集

使用多位元組字符集 --> _mbcs巨集

這幾個巨集一般用來判斷是使用char還是wchar_t,在系統api中使用比較多,如messegebox通過是否定義了unicode巨集來決定是使用lpcstr還是lpcwstr(lpcstr即const char, lpcwstr即const wchar_t):

#ifdef unicode

#define messagebox messageboxw

#else

#define messagebox messageboxa

#endif

// !unicode

上面提到了,定義api時通過判斷unicode巨集是否定義來決定是使用char還是wchar_t,那麼char和wchar_t有什麼不同了?

char和wchar_t是標準c/c++字元型別,並不是windows特有的。 char固定佔1個位元組,wchar_t固定佔2個位元組,從記憶體的角度來看,char、wchar_t和其他資料型別一樣,只是代表一段記憶體塊,用來儲存固定長度的二進位制0或1。 在程式設計時,我們一般習慣於將字串儲到char或wchar_t定義的記憶體空間中,將整形儲存在int定義的記憶體空間中。

所以,用char還是wchar_t來儲存字元,只是記憶體分配和資料儲存上面的事情,它們本身也是與字元編碼無直接關係的( 同樣注意這裡的「直接」二字,第3節會說到)。

vc++編譯器編譯源**的步驟中,涉及編碼處理的步驟主要有2個:

第1步:預處理

1.1) 讀取原始檔,判斷原始檔採用的字元編碼型別。

編譯器判斷原始檔編碼型別的步驟為:

1. 若檔案開始處有bom(ef bb bf),則判定為utf-8編碼;

2. 若沒有bom,則試圖從檔案的前8個位元組來判斷檔案是否像utf-16編碼,如果像,則就判斷為utf-16編碼。

3. 如果既沒bom,也不是utf-16編碼,則使用系統當前的**頁。

1.2) 將原始檔內容轉成源字符集(source character set),預設為utf-8編碼。

現在我們就可以說清楚visual studio字符集設定、char、wchar_t是如何間接影響到字元編碼的了:

visual studio字符集設定

|決定宣告哪乙個巨集(unicode還是_mbcs巨集)

|巨集又決定了api引數使用char還是wchar_t

|編譯器在進行【執行字符集】編碼時對char和wchar_採用不同的處理方式,從而對字元編碼產生了影響。

通過第3節的說明,很容易知道,要開發支援多語言,在任意語言(系統**頁)的windows環境下都正常編譯,且執行起來沒有亂碼的程式,需要遵循如下原則:

**檔案採用utf-8 with bom編碼。

visual studio字符集設定為unicode字符集。

使用wchar_t。

做到上面3步,你的**被別人從github上clone下來編譯,不會因為你**中含有中文等字元,產生類似error c2015這樣的編譯錯誤,更不會產生亂碼。

本文介紹的方法只用來解決硬編碼字元亂碼的問題,至於資料傳輸中的亂碼,需要統一字元編碼來解決。

參考:

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

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

撥開字元編碼的迷霧

為什麼這樣的json會解析失敗?為什麼介面上韓文顯示亂碼?ascii和ansi有什麼區別?相信不少人在字元編碼上面摔過跟頭,這篇文章針對開發中需要了解的字元編碼知識進行了簡要的講解,希望能夠對大家有所幫助。字符集就是一系列用於顯示的字元的集合。ascii字符集由美國國家標準協會 american n...

撥開字元編碼的迷霧 字元編碼轉換

撥開字元編碼的迷霧 字元編碼概述 撥開字元編碼的迷霧 編譯器如何處理檔案編碼 撥開字元編碼的迷霧 字元編碼轉換 本文介紹使用windows api進行字元編碼的轉換,涉及widechartomultibyte和multibytetowidechar2個api,api介面名中的multibyte對應著...