C語言MultiByteToWideChar和WideCharToMultiByte案例詳解_第1頁
C語言MultiByteToWideChar和WideCharToMultiByte案例詳解_第2頁
C語言MultiByteToWideChar和WideCharToMultiByte案例詳解_第3頁
C語言MultiByteToWideChar和WideCharToMultiByte案例詳解_第4頁
C語言MultiByteToWideChar和WideCharToMultiByte案例詳解_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

第C語言MultiByteToWideChar和WideCharToMultiByte案例詳解與MultiByteToWideChar()函數(shù)中的參數(shù)類似,但是多了兩個參數(shù):

lpDefaultChar和pfUsedDefaultChar:只有當(dāng)WideCharToMultiByte函數(shù)遇到一個寬字節(jié)字符,而該字符在uCodePage參數(shù)標(biāo)識的代碼頁中并沒有它的表示法時,WideCharToMultiByte函數(shù)才使用這兩個參數(shù)。(通常都取值為NULL)

1如果寬字節(jié)字符不能被轉(zhuǎn)換,該函數(shù)便使用lpDefaultChar參數(shù)指向的字符。如果該參數(shù)是NULL(這是大多數(shù)情況下的參數(shù)值),那么該函數(shù)使用系統(tǒng)的默認(rèn)字符。該默認(rèn)字符通常是個問號。這對于文件名來說是危險的,因為問號是個通配符。

2pfUsedDefaultChar參數(shù)指向一個布爾變量,如果Unicode字符串中至少有一個字符不能轉(zhuǎn)換成等價多字節(jié)字符,那么函數(shù)就將該變量置為TRUE。如果所有字符均被成功地轉(zhuǎn)換,那么該函數(shù)就將該變量置為FALSE。當(dāng)函數(shù)返回以便檢查寬字節(jié)字符串是否被成功地轉(zhuǎn)換后,可以測試該變量。

返回值:

如果函數(shù)運行成功,并且cchMultiByte不為零,返回值是由lpMultiByteStr指向的緩沖區(qū)中寫入的字節(jié)數(shù);

如果函數(shù)運行成功,并且cchMultiByte為零,返回值是接收到待轉(zhuǎn)換字符串的緩沖區(qū)所必需的字節(jié)數(shù)。(此種情況用來獲取轉(zhuǎn)換所需Char的個數(shù))

如果函數(shù)運行失敗,返回值為零。

若想獲得更多錯誤信息,請調(diào)用GetLastError函數(shù)。它可以返回下面所列錯誤代碼:

ERROR_INSUFFICIENT_BJFFER;ERROR_INVALID_FLAGS;

ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。

二、使用方法

(1)將多字節(jié)字符串轉(zhuǎn)為寬字符串:

1)調(diào)用MultiByteToWideChar()函數(shù),設(shè)置cchWideChar參數(shù)為0(用以獲取轉(zhuǎn)換所需的接收緩沖區(qū)大小);

2)獲取輸入緩存的大小,作為cchMultiByte的值;(這樣做是為了節(jié)省空間,也可以給cchMultiByte取值-1(字符串需要以空字符結(jié)尾,否則會出錯))

3)分配足夠的內(nèi)存塊,用于存放轉(zhuǎn)換后的Unicode字符串;

該內(nèi)存塊的大小由前面對cchWideChar()函數(shù)的返回值來決定;(也可以用別的方法,但該方法更節(jié)省內(nèi)存)

4)再次調(diào)用MultiByteToWideChar()函數(shù),這次將緩存的地址作為lpWideCharStr,參數(shù)來傳遞,并傳遞第一次調(diào)用MultiByteToWideChar()函數(shù)時的返回值作為cchWideChar參數(shù)的值;

5)使用轉(zhuǎn)換后的字符串;

6)釋放接收緩沖區(qū)占用的內(nèi)存塊;

示例代碼:

voidmain()

charsBuf[25]={0};

strcpy(sBuf,"我最棒");

//獲取輸入緩存大小

intsBufSize=strlen(sBuf);

//獲取輸出緩存大小

//VC++默認(rèn)使用ANSI,故取第一個參數(shù)為CP_ACP

DWORDdBufSize=MultiByteToWideChar(CP_ACP,0,sBuf,sBufSize,NULL,0);

printf("需要wchar_t%u個\n",dBufSize);

wchar_t*dBuf=newwchar_t[dBufSize];

wmemset(dBuf,0,dBufSize);

//進行轉(zhuǎn)換

intnRet=MultiByteToWideChar(CP_ACP,0,sBuf,sBufSize,dBuf,dBufSize);

if(nRet=0)

cout"轉(zhuǎn)換失敗"endl;

DWORDdwErr=GetLastError();

switch(dwErr)

caseERROR_INSUFFICIENT_BUFFER:

printf("ERROR_INSUFFICIENT_BUFFER\n");

break;

caseERROR_INVALID_FLAGS:

printf("ERROR_INVALID_FLAGS\n");

break;

caseERROR_INVALID_PARAMETER:

printf("ERROR_INVALID_PARAMETER\n");

break;

caseERROR_NO_UNICODE_TRANSLATION:

printf("ERROR_NO_UNICODE_TRANSLATION\n");

break;

else

cout"轉(zhuǎn)換成功"endl;

coutdBuf;

delete(dBuf);

}

注意:兩次調(diào)用MultiCharToWideChar()時,形參cchMultiByte的取值需要相同,否則可能會出現(xiàn)接收緩存不足之類的錯誤,從而導(dǎo)致轉(zhuǎn)換失??!

(2)從寬字節(jié)轉(zhuǎn)為窄字節(jié)字符串

步驟與(1)類似,故不贅述

代碼示例如下:

//從寬字符串轉(zhuǎn)換窄字符串

wchar_tsBuf[25]={0};

wcscpy(sBuf,L"我最棒");

//獲取轉(zhuǎn)換所需的目標(biāo)緩存大小

DWORDdBufSize=WideCharToMultiByte(CP_OEMCP,0,sBuf,-1,NULL,0,NULL,FALSE);

//分配目標(biāo)緩存

char*dBuf=newchar[dBufSize];

memset(dBuf,0,dBufSize);

//轉(zhuǎn)換

intnRet=WideCharToMultiByte(CP_OEMCP,0,sBuf,-1,dBuf,dBufSize,NULL,FALSE);

if(nRet=0)

printf("轉(zhuǎn)換失敗\n");

else

printf("轉(zhuǎn)換成功\nAfterConvert:%s\n",dBuf);

delete[]dBuf;

三、MultiByteToWideChar()函數(shù)亂碼的問題

有的朋友可能已經(jīng)發(fā)現(xiàn),在標(biāo)準(zhǔn)的WinCE4.2或WinCE5.0SDK模擬器下,這個函數(shù)都無法正常工作,其轉(zhuǎn)換之后的字符全是亂碼!

及時更改MultiByteToWideChar()參數(shù)也依然如此。不過這個不是代碼問題,其結(jié)癥在于所定制的操作系統(tǒng).如果我們定制的操作系統(tǒng)默認(rèn)語言不是中文,也會出現(xiàn)這種情況。

由于標(biāo)準(zhǔn)的SDK默認(rèn)語言為英文,所以肯定會出現(xiàn)這個問題。而這個問題的解決,不能在簡單地更改控制面板的”區(qū)域選項”的”默認(rèn)語言”,而是要在系統(tǒng)定制的時候,選擇默認(rèn)語言為”中文”。系統(tǒng)定制時選擇默認(rèn)語言的位置于:Platform-Setting…-locale-defaultlanguage,選擇”中文”,然后編譯即可。

Unicode:寬字節(jié)字符集

1.如何取得一個既包含單字節(jié)字符又包含雙字節(jié)字符的字符串的字符個數(shù)?

可以調(diào)用MicrosoftVisualC++的運行期庫包含函數(shù)_mbslen來操作多字節(jié)(既包括單字節(jié)也包括雙字節(jié))字符串。

調(diào)用strlen函數(shù),無法真正了解字符串中究竟有多少字符,它只能告訴你到達結(jié)尾的0之前有多少個字節(jié)。

2.如何對DBCS(雙字節(jié)字符集)字符串進行操作?

函數(shù)描述

PTSTRCharNext(LPCTSTR);返回字符串中下一個字符的地址

PTSTRCharPrev(LPCTSTR,LPCTSTR);返回字符串中上一個字符的地址BOOLIsDBCSLeadByte(BYTE);如果該字節(jié)是DBCS字符的第一個字節(jié),則返回非0值

3.為什么要使用Unicode?

可以很容易地在不同語言之間進行數(shù)據(jù)交換。

使你能夠分配支持所有語言的單個二進制.exe文件或DLL文件。

提高應(yīng)用程序的運行效率。

Windows2000是使用Unicode從頭進行開發(fā)的,如果調(diào)用任何一個Windows函數(shù)并給它傳遞一個ANSI字符串,那么系統(tǒng)首先要將字符串轉(zhuǎn)換成Unicode,然后將Unicode字符串傳遞給操作系統(tǒng)。如果希望函數(shù)返回ANSI字符串,系統(tǒng)就會首先將Unicode字符串轉(zhuǎn)換成ANSI字符串,然后將結(jié)果返回給你的應(yīng)用程序。進行這些字符串的轉(zhuǎn)換需要占用系統(tǒng)的時間和內(nèi)存。通過從頭開始用Unicode來開發(fā)應(yīng)用程序,就能夠使你的應(yīng)用程序更加有效地運行。

WindowsCE本身就是使用Unicode的一種操作系統(tǒng),完全不支持ANSIWindows函數(shù)

Windows98只支持ANSI,只能為ANSI開發(fā)應(yīng)用程序。

Microsoft公司將COM從16位Windows轉(zhuǎn)換成Win32時,公司決定需要字符串的所有COM接口方法都只能接受Unicode字符串。

4.如何編寫Unicode源代碼?

Microsoft公司為Unicode設(shè)計了WindowsAPI,這樣,可以盡量減少代碼的影響。實際上,可以編寫單個源代碼文件,以便使用或者不使用Unicode來對它進行編譯。只需要定義兩個宏(UNICODE和_UNICODE),就可以修改然后重新編譯該源文件。

_UNICODE宏用于C運行期頭文件,而UNICODE宏則用于Windows頭文件。當(dāng)編譯源代碼模塊時,通常必須同時定義這兩個宏。

5.Windows定義的Unicode數(shù)據(jù)類型有哪些?

數(shù)據(jù)類型說明

WCHARUnicode字符

PWSTR指向Unicode字符串的指針

PCWSTR指向一個恒定的Unicode字符串的指針

對應(yīng)的ANSI數(shù)據(jù)類型為CHAR,LPSTR和LPCSTR。

ANSI/Unicode通用數(shù)據(jù)類型為TCHAR,PTSTR,LPCTSTR。

6.如何對Unicode進行操作?

字符集特性實例

ANSI操作函數(shù)以str開頭strcpy

Unicode操作函數(shù)以wcs開頭wcscpy

MBCS操作函數(shù)以_mbs開頭_mbscpy

ANSI/Unicode操作函數(shù)以_tcs開頭_tcscpy(C運行期庫)

ANSI/Unicode操作函數(shù)以lstr開頭lstrcpy(Windows函數(shù))

所有新的和未過時的函數(shù)在Windows2000中都同時擁有ANSI和Unicode兩個版本。ANSI版本函數(shù)結(jié)尾以A表示;Unicode版本函數(shù)結(jié)尾以W表示。Windows會如下定義:

#ifdefUNICODE

#defineCreateWindowExCreateWindowExW

#else

#defineCreateWindowExCreateWindowExA

#endif//!UNICODE

7.列表內(nèi)容

如何表示Unicode字符串常量?

字符集實例

ANSI“string”

UnicodeL“string”

ANSI/UnicodeT(“string”)或_TEXT(“string”)if(szError[0]==_TEXT(‘J')){}

7.為什么應(yīng)當(dāng)盡量使用操作系統(tǒng)函數(shù)?

這將有助于稍稍提高應(yīng)用程序的運行性能,因為操作系統(tǒng)字符串函數(shù)常常被大型應(yīng)用程序比如操作系統(tǒng)的外殼進程Explorer.exe所使用。由于這些函數(shù)使用得很多,因此,在應(yīng)用程序運行時,它們可能已經(jīng)被裝入RAM。

如:StrCat,StrChr,StrCmp和StrCpy等。

8.如何編寫符合ANSI和Unicode的應(yīng)用程序?

(1)將文本串視為字符數(shù)組,而不是chars數(shù)組或字節(jié)數(shù)組。

(2)將通用數(shù)據(jù)類型(如TCHAR和PTSTR)用于文本字符和字符串。

(3)將顯式數(shù)據(jù)類型(如BYTE和PBYTE)用于字節(jié)、字節(jié)指針和數(shù)據(jù)緩存。

(4)將TEXT宏用于原義字符和字符串。

(5)執(zhí)行全局性替換(例如用PTSTR替換PSTR)。

(6)修改字符串運算問題。例如函數(shù)通常希望在字符中傳遞一個緩存的大小,而不是字節(jié)。這意味著不應(yīng)該傳遞sizeof(szBuffer),而應(yīng)該傳遞(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要為字符串分配一個內(nèi)存塊,并且擁有該字符串中的字符數(shù)目,那么請記住要按字節(jié)來分配內(nèi)存。這就是說,應(yīng)該調(diào)用malloc(nCharacters*sizeof(TCHAR)),而不是調(diào)用malloc(nCharacters)。

9.列表內(nèi)容

如何對字符串進行有選擇的比較?

通過調(diào)用CompareString來實現(xiàn)。

標(biāo)志含義

NORM_IGNORECASE忽略字母的大小寫

NORM_IGNOREKANATYPE不區(qū)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論