移动开发中的字符集转换问题
在手机开发中会碰到关于字符类型的转换问题,特别是如果想在程序中支持中文则必须搞清楚某些字符集的表示方法,较常见的是 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;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 码跟 UCS2 和 UTF-8 之间的转换方法可以看上面关于 UCS2 和 UTF-8 的描述。
本文来自:http://blog.csdn.net/dznlong/archive/2007/04/11/1560942.aspx