国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

寬字符和窄字符的一個(gè)坑

2019-11-10 19:24:32
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

學(xué)習(xí)Windows編程的時(shí)候,遇到字符串處理會(huì)讓人非常抓狂,當(dāng)然問(wèn)題的根本還是自己學(xué)藝不精,不過(guò)還是得吐槽一下,造成這一局面的原因是規(guī)則變化多端而又有點(diǎn)不可捉摸,這不,最近就掉到坑里面去了。

先看看下面的這段代碼:

int main(int argn,char* argv[]){    char strA[]="ABC 簡(jiǎn)體中文";    wchar_t strW[]=L"ABC 簡(jiǎn)體中文";    PRintf("%s/n",strA);    wprintf(L"%s/n",strW);    return 0;}

猜猜看,輸出是什么?在我的電腦上(程序使用VS2010編譯通過(guò),Windows 7操作系統(tǒng),簡(jiǎn)體中文版)運(yùn)行的結(jié)果是這樣的:

image

第一個(gè)還好好地,怎么第二個(gè)會(huì)出現(xiàn)三個(gè)問(wèn)號(hào)?

調(diào)試一下試試看,在return 0前面下斷點(diǎn),然后查看內(nèi)存:

image

image

這個(gè)是strA在內(nèi)存中的值:41 42 43 20 bc f2 cc e5 d6 d0 ce c4 00

而strW則是:41 00 42 00 43 00 20 00 80 7b 53 4f 2d 4e 87 65 00 00

首先,我們知道char類(lèi)型占一個(gè)字節(jié),而wchar_t則是占兩個(gè)字節(jié),前面的41,42,43,20就是分別’A’,’B’,’C’和’ ‘(空格),這里表明,寬字符采用的是Little-Endian方式存放兩個(gè)字節(jié)的,接下來(lái)我們把重點(diǎn)都放在漢字上面。

在strA中,表示漢字“簡(jiǎn)體中文”數(shù)據(jù)為bc f2 cc e5 d6 d0 ce c4,而在strW則是80 7b 53 4f 2d 4e 87 65,差別很大,為什么是這樣呢?

這其中涉及到了編碼的問(wèn)題。char類(lèi)型中出現(xiàn)的漢字,采用的是GB2312的編碼規(guī)則,查詢(xún)?cè)摼幋a表,可以發(fā)現(xiàn),“簡(jiǎn)”字的編碼為BCF2,“體”為CCE5,“中”為D6D0,而“文”則為CEC4,這就是strA中中文的表示方式,但是在寬字符strW中,采用的編碼則是Unicode編碼,在Windows平臺(tái)下Unicode編碼值就是UTF-16編碼值。查詢(xún)“簡(jiǎn)體中文”四個(gè)漢字的編碼,可以發(fā)現(xiàn)是7B80 4F53 4E2D 6587,由于計(jì)算機(jī)的架構(gòu)為L(zhǎng)ittle-Endian,需要把高低位字節(jié)互換,這也就是寬字符的表示形式。

根據(jù)網(wǎng)頁(yè)上的說(shuō)明(參考這里)C/C++標(biāo)準(zhǔn)只是聲明wchar_t是一個(gè)可以表示字符集中的任意一個(gè)字符的足夠?qū)挼淖兞款?lèi)型。wchar_t可以用任何encoding編碼方式來(lái)存儲(chǔ)這個(gè)字符,如ANSI、UCS-2或者UCS-4, 甚至是SCU-128,只不過(guò)我們通常是用unicode編碼方式。wchar_t是與實(shí)現(xiàn)相關(guān)的。所以為了可移植性,我們不能假定wchar_t的編碼方式,然后根據(jù)編碼方式做一些相關(guān)性操作,我們只能理解它為一個(gè)足夠?qū)挼淖址?lèi)型。

最后,我們還能順便發(fā)現(xiàn),wprintf函數(shù)在處理文本輸出的時(shí)候,并不處理編碼問(wèn)題,而是直接按多字節(jié)字符順序輸出。

好,現(xiàn)在問(wèn)題的原因找到了,那么該如何解決問(wèn)題呢?

Windows當(dāng)然不會(huì)沒(méi)有想到這個(gè)問(wèn)題,在Windows中,提供了如下兩個(gè)函數(shù):WideCharToMultiByte和MultiByteToWideChar,他們都位于頭文件winnls.h中,分別是將寬字符轉(zhuǎn)化為多字節(jié)和將多字節(jié)轉(zhuǎn)化為寬字符。下面的例子直接給出了轉(zhuǎn)化的代碼,函數(shù)的具體使用方法可以翻閱MSDN。

int main(int argn,char* argv[]){    wchar_t strW[]=L"ABC 簡(jiǎn)體中文";    char* pW2A;    int t=0;    //第一次,確定需要的字節(jié)數(shù)    t=WideCharToMultiByte(CP_ACP,0,strW,-1,NULL,0,NULL,FALSE);    if(t!=0)    {        pW2A=(char*)malloc(t);//分配內(nèi)存,然后運(yùn)行第二次,注意參數(shù)區(qū)別        WideCharToMultiByte(CP_ACP,0,strW,-1,pW2A,t,NULL,FALSE);        printf("%s/n",pW2A);        free(pW2A);    }    return 0;}
這回顯示就沒(méi)有什么問(wèn)題了,長(zhǎng)舒一口氣,暫時(shí)從坑里面爬出來(lái)了。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 西吉县| 密山市| 翁牛特旗| 闵行区| 成安县| 吉隆县| 乌海市| 河池市| 临沭县| 高邮市| 措勤县| 牟定县| 融水| 昌黎县| 遂昌县| 莱西市| 平塘县| 深水埗区| 和顺县| 新晃| 屯昌县| 博爱县| 治县。| 德化县| 舟山市| 台州市| 浦县| 额尔古纳市| 茌平县| 南澳县| 车致| 海林市| 云梦县| 梧州市| 许昌县| 卢龙县| 建阳市| 汝南县| 阜康市| 德惠市| 漯河市|