天天看點

WideCharToMultiByte和MultiByteToWideChar函數的參數詳解及函數用法

MultiByteToWideChar的與WideCharToMultiByte的參數詳解

第一個就是寬字元到多位元組字元轉換函數,函數原型如下:

int WideCharToMultiByte( 
UINT CodePage, 
DWORD dwFlags, 
LPCWSTR lpWideCharStr, 
int cchWideChar, 
LPSTR lpMultiByteStr, 
int cbMultiByte, 
LPCSTR lpDefaultChar, 
LPBOOL lpUsedDefaultChar 
);      

此函數把寬字元串轉換成指定的新的字元串,如ANSI,UTF8等,新字元串不必是多位元組字元集。參數:

CodePage: 指定要轉換成的字元集代碼頁,它可以是任何已經安裝的或系統自帶的字元集,你也可以使用如下所示代碼頁之一。 

CP_ACP 目前系統ANSI代碼頁 

CP_MACCP 目前系統Macintosh代碼頁 

CP_OEMCP 目前系統OEM代碼頁,一種原始裝置制造商硬體掃描碼 

CP_SYMBOL Symbol代碼頁,用于Windows 2000及以後版本,我不明白是什麼 

CP_THREAD_ACP 目前線程ANSI代碼頁,用于Windows 2000及以後版本,我不明白是什麼 

CP_UTF7 UTF-7,設定此值時lpDefaultChar和lpUsedDefaultChar都必須為NULL 

CP_UTF8 UTF-8,設定此值時lpDefaultChar和lpUsedDefaultChar都必須為NULL 

我想最常用的應該是CP_ACP和CP_UTF8了,前者将寬字元轉換為ANSI,後者轉換為UTF8。

dwFlags: 指定如何處理沒有轉換的字元, 但不設此參數函數會運作的更快一些,我都是把它設為0。 可設的值如下表所示: 

WC_NO_BEST_FIT_CHARS 把

不能直接轉換成相應多位元組字元的Unicode字元轉換成lpDefaultChar指定的預設字元。也就是說,如果把Unicode轉換成多位元組字元,

然後再轉換回來,你并不一定得到相同的Unicode字元,因為這期間可能使用了預設字元。此選項可以單獨使用,也可以和其他選項一起使用。 

WC_COMPOSITECHECK 把合成字元轉換成預制的字元。它可以與後三個選項中的任何一個組合使用,如果沒有與他們中的任何一個組合,則與選項WC_SEPCHARS相同。 

WC_ERR_INVALID_CHARS 此選項會緻使函數遇到無效字元時失敗傳回,并且GetLastError會傳回錯誤碼ERROR_NO_UNICODE_TRANSLATION。否則函數會自動丢棄非法字元。此選項隻能用于UTF8。 

WC_DISCARDNS 轉換時丢棄不占空間的字元,與WC_COMPOSITECHECK一起使用 

WC_SEPCHARS 轉換時産生單獨的字元,此是預設轉換選項,與WC_COMPOSITECHECK一起使用 

WC_DEFAULTCHAR 轉換時使用預設字元代替例外的字元,(最常見的如’?’),與WC_COMPOSITECHECK一起使用。 

當指定WC_COMPOSITECHECK時,函數會将合成字元轉換成預制字元。合成字元由一個基字元和一個不占空間的字元(如歐洲國家及漢語拼音的音标)組成,每一個都有不同的字元值。預制字元有一個用于表示基字元和不占空間字元的合成體的單一的字元值。

指定WC_COMPOSITECHECK選項時,也可以使用上表列出的最後3個選項來定制預制字元的轉換規則。這些選項決定了函數在遇到寬字元串的合成字

符沒有對應的預制字元時的行為,他們與WC_COMPOSITECHECK一起使用,如果都沒有指定,函數預設WC_SEPCHARS。

對于下列代碼頁,dwFlags必須為0,否則函數傳回錯誤碼ERROR_INVALID_FLAGS。

50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)

對于UTF8,dwFlags必須為0或WC_ERR_INVALID_CHARS,否則函數都将失敗傳回并設定錯誤碼ERROR_INVALID_FLAGS,你可以調用GetLastError獲得。

lpWideCharStr: 待轉換的寬字元串。 

cchWideChar: 待轉換寬字元串的長度,-1表示轉換到字元串結尾。 

lpMultiByteStr: 接收轉換後輸出新串的緩沖區。 

cbMultiByte: 輸出緩沖區大小,如果為0,lpMultiByteStr将被忽略,函數将傳回所需緩沖區大小而不使用lpMultiByteStr。 

lpDefaultChar: 指

向字元的指針, 在指定編碼裡找不到相應字元時使用此字元作為預設字元代替。 如果為NULL則使用系統預設字元。對于要求此參數為NULL的

dwFlags而使用此參數,函數将失敗傳回并設定錯誤碼ERROR_INVALID_PARAMETER。 

lpUsedDefaultChar:

開關變量的指針,用以表明是否使用過預設字元。對于要求此參數為NULL的dwFlags而使用此參數,函數将失敗傳回并設定錯誤碼

ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都設為NULL,函數會更快一些。 

傳回值: 如果函數成功,且cbMultiByte非0,傳回寫入lpMultiByteStr的位元組數(包括字元串結尾的null);cbMultiByte為0,則傳回轉換所需 

位元組數。函數失敗,傳回0。 

注意:函數WideCharToMultiByte使用不當,會給影響程式的安全。調用此函數會很容易導緻記憶體洩漏,因為

lpWideCharStr指向的輸入緩沖區大小是寬字元數,而lpMultiByteStr指向的輸出緩沖區大小是位元組數。為了避免記憶體洩漏,應確定為

輸出緩沖區指定合适的大小。我的方法是先使cbMultiByte為0調用WideCharToMultiByte一次以獲得所需緩沖區大小,為緩沖區分

配空間,然後再次調用WideCharToMultiByte填充緩沖區,詳見下面的代碼。另外,從Unicode

UTF16向非Unicode字元集轉換可能會導緻資料丢失,因為該字元集可能無法找到表示特定Unicode資料的字元。

wchar_t* pwszUnicode = "Holle, word! 你好,中國! "; 
int iSize; 
char* pszMultiByte; 
iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 
                            0, NULL, NULL); 
pszMultiByte = (char*)malloc((iSize+1)/**sizeof(char)*/); 
WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, 
                    iSize, NULL, NULL);      

第二個是多位元組字元到寬字元轉換函數,函數原型如下: 

 int MultiByteToWideChar( 
UINT CodePage, 
DWORD dwFlags, 
LPCSTR lpMultiByteStr, 
int cbMultiByte, 
LPWSTR lpWideCharStr, 
int cchWideChar 
);      

此函數把多位元組字元串轉換成寬字元串(Unicode),待轉換的字元串并不一定是多位元組的。

此函數的參數,傳回值及注意事項參見上面函數WideCharToMultiByte的說明,這裡隻對dwFlags做簡單解釋。

WideCharToMultiByte和MultiByteToWideChar函數的參數詳解及函數用法

dwFlags: 指定是否轉換成預制字元或合成的寬字元,對控制字元是否使用像形文字,以及怎樣處理無效字元。 

MB_PRECOMPOSED 總是使用預制字元,即有單個預制字元時,就不會使用分解的基字元和不占空間字元。此為函數的預設選項,不能和MB_COMPOSITE合用 

MB_COMPOSITE 總是使用分解字元,即總是使用基字元+不占空間字元的方式 

MB_ERR_INVALID_CHARS 設定此選項,函數遇到非法字元就失敗并傳回錯誤碼ERROR_NO_UNICODE_TRANSLATION,否則丢棄非法字元 

MB_USEGLYPHCHARS 使用像形字元代替控制字元 

對于UTF8,dwFlags必須為0或MB_ERR_INVALID_CHARS,否則函數都将失敗并傳回錯誤碼ERROR_INVALID_FLAGS。

以下函數我沒用過,隻簡要說明之。

int GetTextCharset( HDC hdc );

此函數擷取目前選進的裝置描述表的字元集,等同于GetTextCharsetInfo(hdc, NULL, 0)。

傳回值: 成功傳回字元集辨別,失敗傳回DEFAULT_CHARSET。

該部分轉載自:http://www.cnblogs.com/wanghao111/archive/2009/05/25/1489021.html

WideCharToMultiByte和MultiByteToWideChar函數的用法

為了支援Unicode編碼,需要多位元組與寬位元組之間的互相轉換。這兩個系統函數在使用時需要指定代碼頁。

  WideCharToMultiByte的代碼頁用來标記與新轉換的字元串相關的代碼頁。

  MultiByteToWideChar的代碼頁用來标記與一個多位元組字元串相關的代碼頁。

常用的代碼頁由CP_ACP和CP_UTF8兩個:

  使用CP_ACP代碼頁就實作了ANSI與Unicode之間的轉換。

  使用CP_UTF8代碼頁就實作了UTF-8與Unicode之間的轉換。

1. ANSI to Unicode

wstring ANSIToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,
            0,
            str.c_str(),
            -1,
            NULL,
            0 
wchar_t * pUnicode; 
pUnicode = new wchar_t[unicodeLen+1]; 
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); 
::MultiByteToWideChar( CP_ACP,
         0,
         str.c_str(),
         -1,
         (LPWSTR)pUnicode,
         unicodeLen ); 
wstring rt; 
rt = ( wchar_t* )pUnicode;
delete pUnicode; 
return rt; 
}      

2. Unicode to ANSI

string UnicodeToANSI( const wstring& str )
{
char*     pElementText;
int    iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_ACP,
         0,
         str.c_str(),
         -1,
         NULL,
        0,
         NULL,
         NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_ACP,
         0,
         str.c_str(),
         -1,
         pElementText,
         iTextLen,
         NULL,
         NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}      

3. UTF-8 to Unicode

wstring UTF8ToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_UTF8,
            0,
            str.c_str(),
            -1,
            NULL,
            0 ); 
wchar_t * pUnicode; 
pUnicode = new wchar_t[unicodeLen+1]; 
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); 
::MultiByteToWideChar( CP_UTF8,
         0,
         str.c_str(),
        -1,
         (LPWSTR)pUnicode,
         unicodeLen ); 
wstring rt; 
rt = ( wchar_t* )pUnicode;
delete pUnicode; 
return rt; 
}      

4. Unicode to UTF-8

string UnicodeToUTF8( const wstring& str )
{
char*     pElementText;
int    iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_UTF8,
         0,
         str.c_str(),
         -1,
         NULL,
         0,
         NULL,
         NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_UTF8,
         0,
         str.c_str(),
         -1,
         pElementText,
         iTextLen,
         NULL,
         NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;

}      

該部分轉自:http://www.cnblogs.com/wind-net/archive/2012/10/31/2718329.html