關於wchar的兩個經常使用函數wcstombs和WideCharToMultiByte

寬字符已經困擾我好久了,之前我都是設置項目的屬性把它改成多字節,不用UNICODE。不過如今又遇到寬字節的問題,沒有辦法,只有硬着頭皮學學:
我找到的資料:
http://hi.baidu.com/shongbee2/blog/item/207925546b6cdd5fd10906e0.html
http://hi.baidu.com/shongbee2/blog/item/d4a057511e9539878c5430cb.html
看了以後我才發現原來有wcsXXX的函數專門處理寬字節的,就是strXXX同樣好使。呵呵,我再也不害怕了,就試着本身寫了一下,仍是學了蠻多東西的:
1.有wcsXXX的函數和strXXX的函數對應處理寬字節,wcslen就是求長度的,wcscmp就是比較兩個字符串的。
2.輸出也有相關的操做,wprintf(L」%s%s」);這樣的操做,對文件也能夠用fwprintf函數來輸出。不過我發現貌似cout << wchar;不成功。也發現了一個問題,就是我輸出」相等」這樣一個字符串的時候,發現竟然輸出不正確,不管是控制檯和文件都有錯誤。可見,這個仍是有點小問題的。輸出其餘的例如」12345」等都是正常的。哎,這個函數並不可靠啊。
3.寬字節和普通串的轉換問題,學了兩個函數,一個是:
wcstombs(char* strDes, const wchar*, size_t nMax);這個函數的做用是把wchar轉換爲char。
char* strDes 爲保存轉換後的普通字符串,wchar* 要被轉換的寬字符串。轉換的最大長度。這裏的長度是轉換的個數,而不是字節長度。
mbstowcs() 就是一個相反的過程了,參數就不說了。

另外一套轉換的函數是:
int WideCharToMultiByte(
  UINT CodePage,
  DWORD dwFlags,
  LPCWSTR lpWideCharStr,
  int cchWideChar,
  LPSTR lpMultiByteStr,
  int cbMultiByte,
  LPCSTR lpDefaultChar,    
  LPBOOL lpUsedDefaultChar
);
他的參數不少,上面的鏈接有介紹,這裏就不怎麼細說了。
第一個是編碼的方式,我通常用CP_ACP。第二個是轉換標誌,MSDN上說什麼都不設置更快,而後我就什麼都無論了就用NULL了。具體做用不知道,等遇到了再學。第三個參數就是被轉換的字符串,第四個參數是該字符串的長度,-1表示自動算長度,若是是手動給出,必定要把最後的終結符長度也算上。我以爲仍是-1來的實際。第五個參數就是保存轉換串的指針,第六個參數就是保存串的長度,這裏是單位字符的個數。若是轉換的時候沒有終結符,那麼結果也沒有終結符,要注意下。最後兩個參數就是默認的填充字符和是否使用了默認填充字符,我通常就用NULL代替。

普通串轉寬字節也是相似。
這裏有幾個注意的,必定要保證空間足夠。還有就是那個長度是單位字符個數,而不是字節數,在轉換時,推薦被轉換的字符串長度設置爲-1,由於這樣他會自動算出終結符結束。返回值也是轉換的單位字符個數。例如」相等」有普通串轉換爲寬字節串,返回結果是3,(有終結符),而反過來就是5。若是返回時0 說明轉換失敗。

心得:雖然WideCharToMultiByte的參數要多,感受用的沒有wcstombs爽,但是他的準確好高一些,要轉換的話,還用用WideCharToMultiByte比較合適,還有就是雖然有一套wcsXXX的庫函數,惋惜輸出仍是出現問題的。若是全都用寬字節,那沒有關係wcsxxx的函數仍是蠻好用的。還有一個疑惑我明明查字典multi是多的意思也就是說multibyte是多字節,個人中文版VS2005配置裏面也是說的多字節。搞不懂爲何要用寬字節呢?多是多字節編碼很差用吧。呵呵。 廢話也說完了,奉上源代碼:html

#include  < iostream >
#include 
< fstream >
#include 
< windows.h >
using   namespace  std;

int  main()
{
    FILE
*  fp ;
    WCHAR wchar[
5 =  L " 相等相等 " ;         // 定義一個寬字節的變量,初始爲"相等"
    fp  =  fopen( " 1.txt " " w+ " );         // 打開文件稱奧作
    fwprintf(fp, L " %s\n " , wchar);     // 輸出到文件
    fclose(fp);                         // 關閉文件
    WCHAR wc2[ 5 ];                     // 定義第二個寬字節變量
    
    
// wc開始的有不少寬字節的操做。都和str相對應。
    wcscpy(wc2, wchar);                 // 複製。
     int  n  =  wcscmp(wc2, wchar);         // 比較
     if  (n  ==   0 )
    {
        wprintf(L
" 相等\n " );             // 這裏是否注意到沒有wprintf有問題的。
    }

    
char  str[ 10 ];                     // 定義char字符。
    n  =  wcstombs(str, wc2,  9 );         // 寬字節轉換爲muiltychar
    printf( " %s\n " , str);             // 輸出結果

    
for  ( int  i  =   0 ; i  <   5 ++ i)
    {
        wc2[i] 
=  L ' 1 '   +  i;
    }
    wc2[
4 =   0 ;

    n 
=  wcstombs(str, wc2,  9 );         // 寬字節轉換爲muiltychar
    printf( " %s\n " , str);             // 輸出結果
    
// 另外的方式轉換
    n  =  WideCharToMultiByte(CP_ACP, NULL, wchar, wcslen(wchar)  +   1 , str,  10 0 0 );
    printf(
" %s\n " , str);
    
char  str2[ 10 =   " 加一 " ;
    WCHAR wc3[
10 ];
    n 
=  MultiByteToWideChar(CP_ACP, NULL, str2, strlen(str2)  +   1 , wc3,  10 );     // char到寬字節。

    system(
" pause " );
    
return   0 ;}
相關文章
相關標籤/搜索