UNICODE和ANSI字符串的轉換

繼上集故事《多字符集(ANSI)和UNICODE及字符串處理方式準則 》,我們現在有一些特殊需求:

有時候我們的字符串是多字符型,我們卻需要使用寬字符型;有的時候卻恰恰相反。

Windows爲我們提供了這樣的函數來處理這個問題:

1.MultiByteToWideChar

函數功能: 該函數映射一個字符串到一個寬字符 (unicode)的字符串。由該函數映射的字符串沒必要是多字節字符組。

函數原型: int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte,

LPWSTR lpWideCharStr, int cchWideChar);

參數:

CodePage:指定執行轉換的代碼頁,這個參數可以爲系統已安裝或有效的任何代碼頁所給定的值。你也 可以指定其爲下面的任意一值:

CP_ACP:ANSI代碼頁;CP_MACCP:Macintosh代碼 頁;CP_OEMCP:OEM代碼頁;

CP_SYMBOL:符號代碼頁(42);CP_THREAD_ACP:當前線程ANSI代碼 頁;

CP_UTF7:使用UTF-7轉換;CP_UTF8:使用UTF-8轉換。

dwFlags:一組位標記用以指出是否未轉換成預作或寬字符(若組合形式存在),是否使用象 形文字替代控制字符,以及如何處理無效字符。你可以指定下面是標記常量的組合,含義如下:

MB_PRECOMPOSED:通常使用預作字符——就是說,由一個基本字符和一個非空字符組 成的字符只有一個單一的字符值。這是缺省的轉換選擇。不能與

MB_COMPOSITE值一起使用。

MB_COMPOSITE:通常使用組合字符——就是說,由一個基本字符和一個非空字符組成的 字符分別有不同的字符值。不能與MB_PRECOMPOSED值一起使用。

MB_ERR_INVALID_CHARS:如果函數遇到無效的輸入字符,它將運行失敗,且 GetLastErro返回ERROR_NO_UNICODE_TRANSLATION值。

MB_USEGLYPHCHARS:使用象形文字替代控制字符。

組合字符由一個基礎字符和一個非空字符構成,每一個都有不同的字符值。每個預作字符都有單一的 字符值給基礎/非空字符的組成。在字符è中,e就是基礎字符,而重音符標記就是非空字符。

函數的缺省動作是轉換成預作的形式。如果預作的形式不存在,函數將嘗試轉換成組合形式。

標記MB_PRECOMPOSED和MB_COMPOSITE是互斥的,而標記 MB_USEGLYPHCHARS和MB_ERR_INVALID_CHARS則不管其它標記如何都可以設置。

lpMultiByteStr:指向將被轉換字符串的字符。

cchMultiByte:指定由參數lpMultiByteStr指向的字符串中字節的個 數。如果這個值爲-1,字符串將被設定爲以NULL爲結束符的字符串,並且自動計算長度。

lpWideCharStr:指向接收被轉換字符串的緩衝區。

cchWideChar:指定由參數lpWideCharStr指向的緩衝區的字節個數。若此 值爲零,函數返回緩衝區所必需的寬字符數,在這種情況下,lpWideCharStr中的緩衝區不被使用。

返回值

如果函數運行成功,並且cchWideChar不爲零,返回值是由lpWideCharStr指向的緩 衝區中寫入的寬字符數;如果函數運行成功,並且cchMultiByte爲零,返回值是接收到待轉換字符串的緩衝區所需求的寬字符數大小。如果函數運行失 敗,返回值爲零。若想獲得更多錯誤信息,請調用GetLastError函數。它可以返回下面所列錯誤代碼:

ERROR_INSUFFICIENT_BUFFER;ERROR_INVALID_FLAGS;

ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。

注意

指針lpMultiByteStr和lpWideCharStr必須不一樣。如果一樣,函數將失 敗,GetLastError將返回ERROR_INVALID_PARAMETER的值。

如果MB_ERR_INVALID_CHARS被設置並且在資源字符串中遇到無效的字符時,函 數將失敗。如果MB_ERR_INVALID_CHARS不被設置,或是DBCS串中發現了頭字節而沒有有效的尾字節,無效字符將轉換爲缺省字符,但不是 資源字符串中的缺省字符。當無效字符被發現,且MB_ERR_INVALID_CHARS值被設置,函數返回零,GetLastErro顯示 ERROR_NO_UNICODE_TRANSLATION的出錯信息。

2.WideCharToMultiByte

函數功能: 該函數映射一個unicode字符串到一個多字節字符串。

函數原型: int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, LPCSTR lpMultiByteStr, int cchMultiByte, LPCSTR lpDefaultChar, PBOOL pfUsedDefaultChar );

參數:

CodePage:指定執行轉換的代碼頁,這個參數可以爲系統已安裝或有效的任 何代碼頁所給定的值。你也可以指定其爲下面的任意一值:

CP_ACP:ANSI代碼頁;CP_MACCP:Macintosh代碼 頁;CP_OEMCP:OEM代碼頁;

CP_SYMBOL:符號代碼頁(42);CP_THREAD_ACP:當前線索ANSI代碼 頁;

CP_UTF7:使用UTF-7轉換;CP_UTF8:使用UTF-8轉換。

dwFlags [in] Specifies the handling of unmapped characters. The function performs more quickly when none of these flags is set. The following flag constants are defined.

Value

Meaning

WC_NO_BEST_FIT_CHARS

Windows 98/Me and Windows 2000/XP: Any Unicode characters that do not translate directly to multibyte equivalents are translated to the default character (see lpDefaultChar parameter). In other words, if translating from Unicode to multibyte and back to Unicode again does not yield the exact same Unicode character, the default character is used. This flag can be used by itself or in combination with the other dwFlag options.

WC_COMPOSITECHECK

Convert composite characters to precomposed characters.

WC_DISCARDNS

Discard nonspacing characters during conversion.

WC_SEPCHARS

Generate separate characters during conversion. This is the default conversion behavior.

WC_DEFAULTCHAR

Replace exceptions with the default character during conversion.

When WC_COMPOSITECHECK is specified, the function converts composite characters to precomposed characters. A composite character consists of a base character and a nonspacing character, each having different character values. A precomposed character has a single character value for a base/nonspacing character combination. In the character , the e is the base character, and the accent grave mark is the nonspacing character.

When an application specifies WC_COMPOSITECHECK, it can use the last three flags in this list (WC_DISCARDNS, WC_SEPCHARS, and WC_DEFAULTCHAR) to customize the conversion to precomposed characters. These flags determine the function's behavior when there is no precomposed mapping for a base/nonspace character combination in a wide-character string. These last three flags can only be used if the WC_COMPOSITECHECK flag is set.

The function's default behavior is to generate separate characters (WC_SEPCHARS) for unmapped composite characters.

For the code pages in the following table, dwFlags must be zero, otherwise the function fails with ERROR_INVALID_FLAGS.

50220 50221

50222

50225

50227 50229

52936

54936

57002 through 57011 65000 (UTF7)

65001 (UTF8)

42 (Symbol)

相關變量

lpWideCharStr:指向將被轉換的unicode字符串。

cchWideChar:指定由參數lpWideCharStr指向的緩衝區的 字符個數。如果這個值爲-1,字符串將被設定爲以NULL爲結束符的字符串,並且自動計算長度。

lpMultiByteStr:指向接收被轉換字符串的緩衝區。

cchMultiByte:指定由參數lpMultiByteStr指向的緩衝 區最大值(用字節來計量)。若此值爲零,函數返回lpMultiByteStr指向的目標緩衝區所必需的字節數,在這種情況 下,lpMultiByteStr參數通常爲NULL。

lpDefaultChar和pfUsedDefaultChar: 只有當WideCharToMultiByte函數遇到一個寬字節字符,而該字符在uCodePage參數標識的代碼頁中並沒有它的表示法 時,WideCharToMultiByte函數才使用這兩個參數。如果寬字節字符不能被轉換,該函數便使用lpDefaultChar參數指向的字符。 如果該參數是NULL(這是大多數情況下的參數值),那麼該函數使用系統的默認字符。該默認字符通常是個問號。這對於文件名來說是危險的,因爲問號是個通 配符。pfUsedDefaultChar參數指向一個布爾變量,如果Unicode字符串中至少有一個字符不能轉換成等價多字節字符,那麼函數就將該變 量置爲TRUE。如果所有字符均被成功地轉換,那麼該函數就將該變量置爲FALSE。當函數返回以便檢查寬字節字符串是否被成功地轉換後,可以測試該變 量。

返回值: 如果函數運行成功,並且cchMultiByte不爲零,返回值是由 lpMultiByteStr指向的緩衝區中寫入的字節數;如果函數運行成功,並且cchMultiByte爲零,返回值是接收到待轉換字符串的緩衝區所 必需的字節數。如果函數運行失敗,返回值爲零。若想獲得更多錯誤信息,請調用GetLastError函數。它可以返回下面所列錯誤代碼:

ERROR_INSUFFICIENT_BJFFER;ERROR_INVALID_FLAGS;

ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。

注意: 指針lpMultiByteStr和lpWideCharStr必須不一樣。如果一樣, 函數將失敗,GetLastError將返回ERROR_INVALID_PARAMETER的值。

除此之外,還有幾個比較有意思的字符串處理函數:

1.GetTextCharsetInfo

函數功能: 返回關於選入指定的設備描述表內的當前字體信息。

函數原型

int GetTextCharsetInfo(
__in HDC hdc,
__out LPFONTSIGNATURE lpSig,
__in DWORD dwFlags
);

參數

hdc [in] 設備描述表的句柄。

lpSig [out] 可選。指向一個 FONTSIGNATURE 數據結構的指針,該指針接收字體簽名信息。

如果一個 True Type 字體被選入當前的設別描述表,結構會接收能夠標識編碼頁和Unicode 子範圍的字體符號。

如果字體不是 True Type ,則結構會接收到0.此時,應用程序應使用 TranslateCharsetInfo 函數來獲得原始的字體簽名。

如果應用程序不需要 FONTSIGNATURE 信息時,可以將該參數設爲NULL。此時,應用程序也可以調用GetTextCharset 函數,而且調用該函數與調用GetTextCharset函數是一個效果。

dwFlags [in] 保留。必須爲0.

返回值

如果超過,返回一個值用來標識選入設備描述表內的字體的字符集信息。如果函數失敗,返回值是  DEFAULT_CHARSET.

2.GetTextCharset
函數功能:
此函數獲取當前選進的設備描述表的字符集,等同於GetTextCharsetInfo(hdc,   NULL,   0)。

函數原型: int   GetTextCharset(   HDC   hdc   );

返回值:   成功返回字符集標識,失敗返回DEFAULT_CHARSET。

3.BOOL   IsDBCSLeadByte(   BYTE   TestChar   );
此函數使用當前WindowsANSI代碼頁判斷指定字節是不是一個潛在的雙字節字符(DBCS)的引導字節。若使用其他代碼頁,請用

IsDBCSLeadByteEx函數。

4.BOOL   IsDBCSLeadByteEx( UINT   CodePage, BYTE   TestChar );
此函數判斷指定字節是不是一個潛在的雙字節字符(DBCS)的引導字節。
CodePage可用的值有:CP_ACP,CP_MACCP,CP_OEMCP,CP_THREAD_ACP。

5. BOOL   IsTextUnicode( CONST   VOID*   pBuffer, int   cb, LPINT   lpi );
此函數判斷指定緩衝區裏是否可能會有某種格式的Unicode文本。這個函數判斷方式並不準確,所以可能會返回錯誤結果。記事本就是使用

了這個函數,所以有時候會出現亂碼。所以請謹慎使用這個函數。

還有三個Windows不推薦使用的函數:NlsDllCodePageTranslation,UnicodeToBytes和BytesToUnicode,此處不作過多介紹了。

其中,我們重點關注的還是MultiByteToWideChar和WideCharToMultiByte這兩個函數,具體這兩個函數的使用方式,

請關注下集故事《讓你的程序更加適用——使用ANSI和UNICODE導出函數》


同系列文章參看:

《多字符集(ANSI)和UNICODE及字符串處理方式準則》

 

《 讓你的程序更加適用——使用ANSI和UNICODE導出函數 》



發佈了44 篇原創文章 · 獲贊 4 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章