WCHAR我不再懼怕了

http://www.cppblog.com/shongbee2/archive/2009/04/28/81349.html


寬字符已經困擾我很久了,以前我都是設置項目的屬性把它改爲多字節,不用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配置裏面也是說的多字節。搞不懂爲什麼要用寬字節呢?可能是多字節編碼不好用吧。呵呵。 廢話也說完了,奉上源代碼:

#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章