移動開發中的字符集轉換問題

2021-08-22 15:31:56 字數 3029 閱讀 3713

在手機開發中會碰到關於字元型別的轉換問題,特別是如果想在程式中支援中文則必須搞清楚某些字符集的表示方法,較常見的是 ucs2 、 utf-8 、 ascii 字符集,對於 gb2312 碼則較少平台支援,所以往往要做的轉換是把 gb2312 碼轉換成 ucs2 或 utf-8 碼。

1. ucs2

ucs2 碼是用兩個位元組表示乙個字元,如果字元是 ascii 碼中的字元,則乙個位元組為空 ( 值為 0) ,另乙個位元組為原 ascii 碼的值。 ucs2 字元中的兩個位元組有個位元組順序的問題,不同平台中兩個位元組的順序也許是相反的,所以在把 ucs2 字元轉換成其它字元時,要先弄清楚位元組順序,否則轉換出來的字元很有可能是亂碼。

ucs2 à ascii :要把 ucs2 轉換成 ascii 碼,只要把其中為 0 的位元組去掉就可以了。

ucs2 à utf-8 : ucs2 和 utf-8 字元有一定的必然關係,所以轉換有乙個固定的方法,實現方法如下面的**所示: ( 在 windows ce 中可以呼叫 widechartomultibyte 來實現,其中第乙個引數設為 cp_utf8)

char * ucs2toutf8(char *str,unsigned long len)

unsigned long res,i;

char *p,*q,*utf8 = null;

if(str==0) return 0;

p=str;

res=0;

q=(char*)malloc(len*3+1);

if(q==null)

return null;

if(q)

utf8=q;

p=str;

for(i=0;iif((*p==0x00)&&(*(p+1)<0xa0))

*q++=*(p+1);

p+=2;

else if(*p<0x08)

*q++=(char)(0xc0 | (char)(*p<<2) | (char)(*(p+1)>>6));

*q++=(char)(0x80 | *(p+1) & 0x3f);

p+=2;

}else

*q++=(char)(0xe0 | (char)(*p>>4));

*q++=(char)(0x80 | (char)((*p & 0x0f)<<2) | (char)(*(p+1)>>6));

*q++=(char)(0x80 | *(p+1) & 0x3f);

p+=2;

*q='\0';

return utf8;

ucs2 à gb2312: 要把 ucs2 字元轉換成 gb2312 字元並不是一件容易的事,因為二者之間沒有固定的對應關係,必須根據對映表來進行轉換,所以系統平台如果沒有提供轉換方法而要自己去實現則是件很麻煩的事:你要自己建立一張對映表,然後實現在對映表中查詢。在 windows ce 中可以呼叫 widechartomultibyte 函式來實現 ( 其中第乙個引數值必須是 936) 。

2. utf-8

utf-8 字元由乙個以上的位元組組成,其中可以根據第乙個位元組來判斷該字元的長度:第乙個位元組中高位連續幾個值為 1 的個數即表示該字元有多少個位元組,如果是由兩個以上的位元組組成,則第二個位元組以後的所有位元組高兩位都是「 10 」。 ascii 碼和 utf-8 字元表示形式是一樣的,所以二者之間可以不用進行特殊轉換。 utf-8 字元的乙個優勢是沒有位元組順序,不象 ucs2 有位元組順序之分,所以很多平台採用了 utf-8 字元來表示,其實 utf-8 在網路通訊中是最常用的。

utf-8 à ucs2 :只要把 utf-8 字元中表示位元組個數的 1 和緊隨其後的 0 去掉,以及後面位元組頭兩位的「 10 」去掉,最後重新合併剩下的位,組合起來就是 ucs2 字元了,當然,如果 utf-8 字元是 ascii 碼,則處理方法是不一樣的:要加個空位元組。處理方法如下面的**: ( 在 windows ce 中可以呼叫 multibytetowidechar 來實現,其中第乙個引數設為 cp_utf8)

char * utf8toucs2(char *str,unsigned long *len)

unsigned long res,i;

char *p,*q,*ucs2 = null;

if(str==0) return 0;

p=str;

res=0;

q=(char*)malloc(*len*2+1);

if(q==null)

return null;

if(q) ucs2=q;

p=str;

for(i=0;i<*len;)

if(*p<0xa0)

*q++=0x00;

*q++=*p++;

i++;

else if(*p<0xe0)

*q++=(char)(*p>>2 & 0x07);

*q++=(char)(*p<<6|(*(p+1)&0x3f));

p+=2;

i+=2;

}else

*q++=(char)(*p<<4|(char)(*(p+1)>>2)&0x0f);

*q++=(char)(*(p+1)<<6|(*(p+2)&0x3f));

p+=3;

i+=3;

if(len != null)

*len=(unsigned long)(q-ucs2);

return ucs2;

utf-8 à gb2312 :同 ucs2 一樣,沒有直接的對應關係,大部分平台沒有提供二者之間的直接轉換方法,必須先把 utf-8 轉換成 ucs2 字元,然後再把 ucs2 字元轉換成 gb2312 字元,反過來要把 gb2312 字元轉換成 utf-8 字元,也是要先轉換成 ucs2 字元。

3. ascii

這個是在程式中最常用的也是最簡單的字元,判斷乙個字元是否是 ascii 碼方法非常簡單:只要看位元組中最高位值是否為 0 ,若為 0 則是 ascii 碼。 ascii 碼跟 ucs2 和 utf-8 之間的轉換方法可以看上面關於 ucs2 和 utf-8 的描述。

移動開發中的字符集轉換問題

在手機開發中會碰到關於字元型別的轉換問題,特別是如果想在程式中支援中文則必須搞清楚某些字符集的表示方法,較常見的是 ucs2 utf 8 ascii 字符集,對於 gb2312 碼則較少平台支援,所以往往要做的轉換是把 gb2312 碼轉換成 ucs2 或utf 8碼。1 ucs2 ucs2 碼是用...

mysql字符集問題 mysql字符集問題

我們新建mysql資料庫的時候,需要指定資料庫的字符集,一般我們都是選擇utf8這個字符集,但是還會又乙個utf8mb4這個字符集,好像和utf8有聯絡,今天就來解析一下這兩者的區別。起源mysql在5.5.3之後增加了這個utf8mb4的編碼,mb4就是most bytes 4的意思,專門用來相容...

mysql字符集問題 mysql字符集問題

用show variables like char 檢視mysql的引數,結果應如下 mysql show variables like char variable name value character set client gbk character set connection gbk ch...