下面程序給出的是UTF-8轉(zhuǎn)成Unicode(UCS-2)的函數(shù):
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、小程序定制開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了友誼免費(fèi)建站歡迎大家使用!
#include stdio.h
#include stdlib.h
#include memory.h
#include string.h
int utf8_to_unicode(char* pInput, char** ppOutput)
{
int outputSize = 0; //記錄轉(zhuǎn)換后的Unicode字符串的字節(jié)數(shù)
*ppOutput = (char *)malloc(strlen(pInput) * 2);? //為輸出字符串分配足夠大的內(nèi)存空
memset(*ppOutput, 0, strlen(pInput) * 2);
char *tmp = *ppOutput; //臨時(shí)變量,用于遍歷輸出字符串
while (*pInput)
{
if (*pInput 0x00 *pInput = 0x7F) //處理單字節(jié)UTF8字符(英文字母、數(shù)字)
{
*tmp = *pInput;
tmp++;
*tmp = 0; //小端法表示,在高地址填補(bǔ)0
}
else if (((*pInput) 0xE0) == 0xC0) //處理雙字節(jié)UTF8字符
{
char high = *pInput;
pInput++;
char low = *pInput;
if ((low 0xC0) != 0x80)? //檢查是否為合法的UTF8字符表示
{
return -1; //如果不是則報(bào)錯(cuò)
}
*tmp = (high 6) + (low 0x3F);
tmp++;
*tmp = (high 2) 0x07;
}
else if (((*pInput) 0xF0) == 0xE0)?//處理三字節(jié)UTF8字符
{
char high = *pInput;
pInput++;
char middle = *pInput;
pInput++;
char low = *pInput;
if (((middle 0xC0) != 0x80) || ((low 0xC0) != 0x80))
{
return -1;
}
*tmp = (middle 6) + (low 0x7F);
tmp++;
*tmp = (high 4) + ((middle 2) 0x0F);
}
else //對(duì)于其他字節(jié)數(shù)的UTF8字符不進(jìn)行處理
{
return -1;
}
pInput ++;
tmp ++;
outputSize += 2;
}
*tmp = 0;
tmp++;
*tmp = 0;
return outputSize;
}
擴(kuò)展資料
UTF-8:互聯(lián)網(wǎng)的普及, 強(qiáng)烈要求出現(xiàn)一種統(tǒng)一的編碼方式。 UTF-8就是在互聯(lián)網(wǎng)上使用最廣的一種unicode的實(shí)現(xiàn)方式。其他實(shí)現(xiàn)方式還包括UTF-16和UTF-32,不過(guò)在互聯(lián)網(wǎng)上基本不用。重復(fù)一遍,這里的關(guān)系是,UTF-8是Unicode的實(shí)現(xiàn)方式之一。
UTF-8最大的一個(gè)特點(diǎn),就是它是一種變長(zhǎng)的編碼方式。它可以使用1~6個(gè)字節(jié)表示一個(gè)符號(hào),根據(jù)不同的符號(hào)而變化字節(jié)長(zhǎng)度。
UTF-8的編碼規(guī)則:
UTF-8的編碼規(guī)則很簡(jiǎn)單,只有兩條:
1、對(duì)于單字節(jié)的符號(hào),字節(jié)的第一位設(shè)為0,后面7位為這個(gè)符號(hào)的unicode碼。因此對(duì)于英語(yǔ)字母,UTF-8編碼和ASCII碼是相同的。
2、對(duì)于n字節(jié)的符號(hào)(n1),第一個(gè)字節(jié)的前n位都設(shè)為1,第n+1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒(méi)有提及的二進(jìn)制位,全部為這個(gè)符號(hào)的unicode碼。
#includestdio.h
voidmain()
{
unsignedchara;
printf("enterchar:");
scanf("%C",a);
printf("ascii=%d",a);//強(qiáng)制轉(zhuǎn)化為ascii碼
}
擴(kuò)展資料
C語(yǔ)言ASCII編碼的來(lái)源
ASCII碼
一個(gè)二進(jìn)制位(Bit)有0、1兩種狀態(tài),一個(gè)字節(jié)(Byte)有8個(gè)二進(jìn)制位,有256種狀態(tài),每種狀態(tài)對(duì)應(yīng)一個(gè)符號(hào),就是256個(gè)符號(hào),從00000000到11111111。美國(guó)制定了一套英文字符與二進(jìn)制位的對(duì)應(yīng)關(guān)系,稱為ASCII碼,沿用至今。
ASCII碼規(guī)定了128個(gè)英文字符與二進(jìn)制的對(duì)應(yīng)關(guān)系,占用一個(gè)字節(jié)(實(shí)際上只占用了一個(gè)字節(jié)的后面7位,最前面1位統(tǒng)一規(guī)定為0)。例如,字母a的的ASCII碼為01100001,那么你暫時(shí)可以理解為字母a存儲(chǔ)到內(nèi)存之前會(huì)被轉(zhuǎn)換為01100001,讀取時(shí)遇到01100001也會(huì)轉(zhuǎn)換為a。
1、iconv的含義是將一個(gè)抽象的符號(hào)的編碼進(jìn)行轉(zhuǎn)換。
但是如果一個(gè)符號(hào)比如“個(gè)”,可能在BIG5的編碼中不存在(繁體字中不同)
GBK包含的是簡(jiǎn)體字,BIG5包含的是繁體字,Unicode包含全部,
所以
GBK-Unicode,Big5-Unicode (總是OK)
Unicode-GBK (當(dāng)里面僅包含英文及簡(jiǎn)體時(shí)OK)
Unicode-BIG5 (當(dāng)里面僅包含英文及繁體時(shí)OK)
GBK-Big5 (基本上不行,除非某些字沒(méi)有特別的簡(jiǎn)體字)
GBK-Big5是漢字的簡(jiǎn)繁轉(zhuǎn)換,不是編碼轉(zhuǎn)換,簡(jiǎn)體字轉(zhuǎn)繁體字還有一個(gè)問(wèn)題,一個(gè)簡(jiǎn)體字可能是對(duì)應(yīng)多個(gè)繁體字,這種很難轉(zhuǎn)換正確。繁體字轉(zhuǎn)換成簡(jiǎn)體字相對(duì)難度低。
2、#include iconv.h
size_t iconv(iconv_t cd,
char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
函數(shù)原型, outbuf是一個(gè) char **類型
在函數(shù)手冊(cè)中:
The iconv() function converts one multibyte character at a time, and for each character conversion it increments *inbuf and decrements
*inbytesleft by the number of converted input bytes, it increments *outbuf and decrements *outbytesleft by the number of converted
output bytes
用MultiByteToWideChar和WideCharToMultiByte可以做到編碼的轉(zhuǎn)換。
MultiByteToWideChar是一個(gè)windows API 函數(shù),該函數(shù)映射一個(gè)字符串到一個(gè)寬字符(unicode)的字符串。
函數(shù)原型:
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCSTR lpMultiByteStr,
int cchMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar
);
參數(shù):
CodePage:指定執(zhí)行轉(zhuǎn)換的字符集,這個(gè)參數(shù)可以為系統(tǒng)已安裝或有效的任何字符集所給定的值。你也可以指定其為下面的任意一值:
CP_ACP:ANSI字符集;CP_MACCP:Macintosh代碼頁(yè);CP_OEMCP:OEM代碼頁(yè);
CP_SYMBOL:符號(hào)字符集(42);CP_THREAD_ACP:當(dāng)前線程ANSI代碼頁(yè);
CP_UTF7:使用UTF-7轉(zhuǎn)換;CP_UTF8:使用UTF-8轉(zhuǎn)換。
dwFlags:一組位標(biāo)記用以指出是否未轉(zhuǎn)換成預(yù)作或?qū)捵址ㄈ艚M合形式存在),是否使用象形文字替代控制字符,以及如何處理無(wú)效字符。你可以指定下面是標(biāo)記常量的組合,含義如下:
MB_PRECOMPOSED:通常使用預(yù)作字符——就是說(shuō),由一個(gè)基本字符和一個(gè)非空字符組成的字符只有一個(gè)單一的字符值。這是缺省的轉(zhuǎn)換選擇。不能與
MB_COMPOSITE值一起使用。
MB_COMPOSITE:通常使用組合字符——就是說(shuō),由一個(gè)基本字符和一個(gè)非空字符組成的字符分別有不同的字符值。不能與MB_PRECOMPOSED值一起使用。
MB_ERR_INVALID_CHARS:如果函數(shù)遇到無(wú)效的輸入字符,它將運(yùn)行失敗,且GetLastErro返回ERROR_NO_UNICODE_TRANSLATION值。
MB_USEGLYPHCHARS:使用象形文字替代控制字符。
組合字符由一個(gè)基礎(chǔ)字符和一個(gè)非空字符構(gòu)成,每一個(gè)都有不同的字符值。每個(gè)預(yù)作字符都有單一的字符值給基礎(chǔ)/非空字符的組成。在字符è中,e就是基礎(chǔ)字符,而重音符標(biāo)記就是非空字符。
函數(shù)的缺省動(dòng)作是轉(zhuǎn)換成預(yù)作的形式。如果預(yù)作的形式不存在,函數(shù)將嘗試轉(zhuǎn)換成組合形式。
標(biāo)記MB_PRECOMPOSED和MB_COMPOSITE是互斥的,而標(biāo)記MB_USEGLYPHCHARS和MB_ERR_INVALID_CHARS則不管其它標(biāo)記如何都可以設(shè)置。
lpMultiByteStr:指向?qū)⒈晦D(zhuǎn)換字符串的字符。
cchMultiByte:指定由參數(shù)lpMultiByteStr指向的字符串中字節(jié)的個(gè)數(shù)。如果lpMultiByteStr指定的字符串以空字符終止,可以設(shè)置為-1(如果字符串不是以空字符中止,設(shè)置為-1可能失敗,可能成功),此參數(shù)設(shè)置為0函數(shù)將失敗。
lpWideCharStr:指向接收被轉(zhuǎn)換字符串的緩沖區(qū)。
cchWideChar:指定由參數(shù)lpWideCharStr指向的緩沖區(qū)的寬字符個(gè)數(shù)。若此值為零,函數(shù)返回緩沖區(qū)所必需的寬字符數(shù),在這種情況下,lpWideCharStr中的緩沖區(qū)不被使用。
返回值:
如果函數(shù)運(yùn)行成功,并且cchWideChar不為零,返回值是由lpWideCharStr指向的緩沖區(qū)中寫入的寬字符數(shù);如果函數(shù)運(yùn)行成功,并且cchWideChar為零,返回值是接收到待轉(zhuǎn)換字符串的緩沖區(qū)所需求的寬字符數(shù)大小。如果函數(shù)運(yùn)行失敗,返回值為零。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。它可以返回下面所列錯(cuò)誤代碼:
ERROR_INSUFFICIENT_BUFFER;ERROR_INVALID_FLAGS;
ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。
WideCharToMultiByte,該函數(shù)映射一個(gè)unicode字符串到一個(gè)多字節(jié)字符串。
函數(shù)原型:
int WideCharToMultiByte(
UINT CodePage, //指定執(zhí)行轉(zhuǎn)換的代碼頁(yè)
DWORD dwFlags, //允許你進(jìn)行額外的控制,它會(huì)影響使用了讀音符號(hào)(比如重音)的字符
LPCWSTR lpWideCharStr, //指定要轉(zhuǎn)換為寬字節(jié)字符串的緩沖區(qū)
int cchWideChar, //指定由參數(shù)lpWideCharStr指向的緩沖區(qū)的字符個(gè)數(shù)
LPSTR lpMultiByteStr, //指向接收被轉(zhuǎn)換字符串的緩沖區(qū)
int cchMultiByte, //指定由參數(shù)lpMultiByteStr指向的緩沖區(qū)最大值
LPCSTR lpDefaultChar, //遇到一個(gè)不能轉(zhuǎn)換的寬字符,函數(shù)便會(huì)使用pDefaultChar參數(shù)指向的字符
LPBOOL pfUsedDefaultChar //至少有一個(gè)字符不能轉(zhuǎn)換為其多字節(jié)形式,函數(shù)就會(huì)把這個(gè)變量設(shè)為TRUE
);
參數(shù):
CodePage:指定執(zhí)行轉(zhuǎn)換的代碼頁(yè),這個(gè)參數(shù)可以為系統(tǒng)已安裝或有效的任何代碼頁(yè)所給定的值。你也可以指定其為下面的任意一值:
CP_ACP:ANSI代碼頁(yè);CP_MACCP:Macintosh代碼頁(yè);CP_OEMCP:OEM代碼頁(yè);
CP_SYMBOL:符號(hào)代碼頁(yè)(42);CP_THREAD_ACP:當(dāng)前線程ANSI代碼頁(yè);
CP_UTF7:使用UTF-7轉(zhuǎn)換;CP_UTF8:使用UTF-8轉(zhuǎn)換
返回值:
如果函數(shù)運(yùn)行成功,并且cchMultiByte不為零,返回值是由 lpMultiByteStr指向的緩沖區(qū)中寫入的字節(jié)數(shù);如果函數(shù)運(yùn)行成功,并且cchMultiByte為零,返回值是接收到待轉(zhuǎn)換字符串的緩沖區(qū)所必需的字節(jié)數(shù)。如果函數(shù)運(yùn)行失敗,返回值為零。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。它可以返回下面所列錯(cuò)誤代碼:
ERROR_INSUFFICIENT_BJFFER;ERROR_INVALID_FLAGS;
ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。
注意:指針lpMultiByteStr和lpWideCharStr必須不一樣。如果一樣,函數(shù)將失敗,GetLastError將返回ERROR_INVALID_PARAMETER的值?!?/p>
Windows CE:不支持參數(shù)CodePage中的CP_UTF7和CP_UTF8的值,以及參數(shù)dwFlags中的WC_NO_BEST_FIT_CHARS值。