上一篇文章 已經由第一個參數爲入口,闡述了這兩個函數的意義。
現在提個問題。
如果在將寬字符序列轉化爲多字節序列時,給 WideCharToMultiByte 函數的第一個參數傳入 CP_ACP,則會有怎樣的結果?
CP_ACP 的解釋在 WinNls.h 可以找到:
#define CP_ACP 0 // default to ANSI code page
略加思考,會覺得這裏面有問題:如果寬字符序列中有中文,它如何可以被轉化爲 ANSI 編碼呢?
那麼,第二個問題來了,將一個寬字符序列連續作兩次轉化:
WideCharToMultiByte , MultiByteToWideChar ,傳入的 code page 都是 CP_ACP,鑑於第一步的轉化結果目前來看是未知的,那第二步轉化完成後得到的結果是否和輸入一致呢 ?
先回答第二個問題:宏觀來看,這兩個函數都是編碼轉化函數,字符編碼之所以可以靈活地表示,傳輸,顯示,最核心也是最容易被忽視的一點是,它們是無損轉換 --- 不存在任何信息的丟失,這是根本性問題,否則整個計算機能表示的信息會趨於減少,這是不可能的。
所以基於這點考慮,無損轉化,兩次轉換中,不論給定什麼 code page,只要兩次是一樣的,得到的輸出必然和原始輸入一致。
再回答第一個問題,想法很好,系統設計的人也想到了這個問題,它採取的策略是,當 ANSI 表示不了時,它就會使用系統默認的 code page 去作轉換。對於 windows 而言,在裝系統時,有填入“語言選項”這個步驟,這就是指定了 code page。所以直面的回答是,傳入 CP_ACP 得到的結果和傳入 936 一致(中國), 936 即是 gb2312。
這也是大多數人使用這兩個個函數喜歡傳入的值。
而且,我們使用下面的代碼可以得到系統代碼頁是 936.
DWORD getSystemCodePage()
{
WCHAR pwCodePage[16] = {0};
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTCODEPAGE, pwCodePage, sizeof(pwCodePage));
return _wtoi(pwCodePage);
}
code pag 的定義可以在 msdn 中輸入下面地址看到:
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/intl/unicode_81rn.htm