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

在手機開發中會碰到關於字符類型的轉換問題,特別是如果想在程序中支持中文則必須搞清楚某些字符集的表示方法,較常見的是UCS2UTF-8ASCII字符集,對於GB2312碼則較少平臺支持,所以往往要做的轉換是把GB2312碼轉換成UCS2UTF-8碼。

1.UCS2

UCS2碼是用兩個字節表示一個字符,如果字符是ASCII碼中的字符,則一個字節爲空(值爲0),另一個字節爲原ASCII碼的值。UCS2字符中的兩個字節有個字節順序的問題,不同平臺中兩個字節的順序也許是相反的,所以在把UCS2字符轉換成其它字符時,要先弄清楚字節順序,否則轉換出來的字符很有可能是亂碼。

UCS2àASCII:要把UCS2轉換成ASCII碼,只要把其中爲0的字節去掉就可以了。

UCS2àUTF-8UCS2UTF-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;i<len/2;i++)

{

         if((*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碼跟UCS2UTF-8之間的轉換方法可以看上面關於UCS2UTF-8的描述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章