寬字符已經(jīng)困擾我很久了,以前我都是設(shè)置項(xiàng)目的屬性把它改為多字節(jié),不用UNICODE。不過(guò)現(xiàn)在又遇到寬字節(jié)的問(wèn)題,沒(méi)有辦法,只有硬著頭皮學(xué)學(xué):
我找到的資料:
http://hi.baidu.com/shongbee2/blog/item/207925546b6cdd5fd10906e0.htmlhttp://hi.baidu.com/shongbee2/blog/item/d4a057511e9539878c5430cb.html看了之后我才發(fā)現(xiàn)原來(lái)有wcsXXX的函數(shù)專門處理寬字節(jié)的,就是strXXX一樣好使。呵呵,我不再懼怕了,就試著自己寫了一下,還是學(xué)了蠻多東西的:
1.有wcsXXX的函數(shù)和strXXX的函數(shù)對(duì)應(yīng)處理寬字節(jié),wcslen就是求長(zhǎng)度的,wcscmp就是比較兩個(gè)字符串的。
2.輸出也有相關(guān)的操作,wprintf(L”%s%s”);這樣的操作,對(duì)文件也可以用fwprintf函數(shù)來(lái)輸出。不過(guò)我發(fā)現(xiàn)貌似cout << wchar;不成功。也發(fā)現(xiàn)了一個(gè)問(wèn)題,就是我輸出”相等”這樣一個(gè)字符串的時(shí)候,發(fā)現(xiàn)居然輸出不正確,無(wú)論是控制臺(tái)和文件都有錯(cuò)誤。可見(jiàn),這個(gè)還是有點(diǎn)小問(wèn)題的。輸出其他的例如”12345”等都是正常的。哎,這個(gè)函數(shù)并不可靠啊。
3.寬字節(jié)和普通串的轉(zhuǎn)換問(wèn)題,學(xué)了兩個(gè)函數(shù),一個(gè)是:
wcstombs(char* strDes, const wchar*, size_t nMax);這個(gè)函數(shù)的作用是把wchar轉(zhuǎn)換為char。
char* strDes 為保存轉(zhuǎn)換后的普通字符串,wchar* 要被轉(zhuǎn)換的寬字符串。轉(zhuǎn)換的最大長(zhǎng)度。這里的長(zhǎng)度是轉(zhuǎn)換的個(gè)數(shù),而不是字節(jié)長(zhǎng)度。
mbstowcs() 就是一個(gè)相反的過(guò)程了,參數(shù)就不說(shuō)了。
另一套轉(zhuǎn)換的函數(shù)是:
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);
他的參數(shù)很多,上面的連接有介紹,這里就不怎么細(xì)說(shuō)了。
第一個(gè)是編碼的方式,我一般用CP_ACP。第二個(gè)是轉(zhuǎn)換標(biāo)志,MSDN上說(shuō)什么都不設(shè)置更快,然后我就什么都不管了就用NULL了。具體作用不知道,等遇到了再學(xué)。第三個(gè)參數(shù)就是被轉(zhuǎn)換的字符串,第四個(gè)參數(shù)是該字符串的長(zhǎng)度,-1表示自動(dòng)算長(zhǎng)度,如果是手動(dòng)給出,一定要把最后的終結(jié)符長(zhǎng)度也算上。我覺(jué)得還是-1來(lái)的實(shí)際。第五個(gè)參數(shù)就是保存轉(zhuǎn)換串的指針,第六個(gè)參數(shù)就是保存串的長(zhǎng)度,這里是單位字符的個(gè)數(shù)。如果轉(zhuǎn)換的時(shí)候沒(méi)有終結(jié)符,那么結(jié)果也沒(méi)有終結(jié)符,要注意下。最后兩個(gè)參數(shù)就是默認(rèn)的填充字符和是否使用了默認(rèn)填充字符,我一般就用NULL代替。
普通串轉(zhuǎn)寬字節(jié)也是類似。
這里有幾個(gè)注意的,一定要保證空間足夠。還有就是那個(gè)長(zhǎng)度是單位字符個(gè)數(shù),而不是字節(jié)數(shù),在轉(zhuǎn)換時(shí),推薦被轉(zhuǎn)換的字符串長(zhǎng)度設(shè)置為-1,因?yàn)檫@樣他會(huì)自動(dòng)算出終結(jié)符結(jié)束。返回值也是轉(zhuǎn)換的單位字符個(gè)數(shù)。例如”相等”有普通串轉(zhuǎn)換為寬字節(jié)串,返回結(jié)果是3,(有終結(jié)符),而反過(guò)來(lái)就是5。如果返回時(shí)0 說(shuō)明轉(zhuǎn)換失敗。
心得:雖然WideCharToMultiByte的參數(shù)要多,感覺(jué)用的沒(méi)有wcstombs爽,可是他的準(zhǔn)確好高一些,要轉(zhuǎn)換的話,還用用WideCharToMultiByte比較合適,還有就是雖然有一套wcsXXX的庫(kù)函數(shù),可惜輸出還是出現(xiàn)問(wèn)題的。如果全都用寬字節(jié),那沒(méi)有關(guān)系wcsxxx的函數(shù)還是蠻好用的。還有一個(gè)疑惑我明明查字典multi是多的意思也就是說(shuō)multibyte是多字節(jié),我的中文版VS2005配置里面也是說(shuō)的多字節(jié)。搞不懂為什么要用寬字節(jié)呢?可能是多字節(jié)編碼不好用吧。呵呵。 廢話也說(shuō)完了,奉上源代碼:
#include <iostream>
#include <fstream>
#include <windows.h>
using namespace std;
int main()
{
FILE* fp ;
WCHAR wchar[5] = L"相等相等"; //定義一個(gè)寬字節(jié)的變量,初始為"相等"
fp = fopen("1.txt", "w+"); //打開(kāi)文件稱奧做
fwprintf(fp, L"%s\n", wchar); //輸出到文件
fclose(fp); //關(guān)閉文件
WCHAR wc2[5]; //定義第二個(gè)寬字節(jié)變量
//wc開(kāi)始的有很多寬字節(jié)的操作。都和str相對(duì)應(yīng)。
wcscpy(wc2, wchar); //復(fù)制。
int n = wcscmp(wc2, wchar); //比較
if (n == 0)
{
wprintf(L"相等\n"); //這里是否注意到?jīng)]有wprintf有問(wèn)題的。
}
char str[10]; //定義char字符。
n = wcstombs(str, wc2, 9); //寬字節(jié)轉(zhuǎn)換為muiltychar
printf("%s\n", str); //輸出結(jié)果
for (int i = 0; i < 5; ++i)
{
wc2[i] = L'1' + i;
}
wc2[4] = 0;
n = wcstombs(str, wc2, 9); //寬字節(jié)轉(zhuǎn)換為muiltychar
printf("%s\n", str); //輸出結(jié)果
//另外的方式轉(zhuǎn)換
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到寬字節(jié)。
system("pause");
return 0;
}
不要臉的再次放入精華區(qū),因?yàn)槲矣X(jué)得他困擾我太久了。呵呵