GBK与UTF-8之间的转化
GBK编码与UTF-8之间的转化。
第一种是先将 GBK->Unicode->UTF-8;
第二种是通过iconv库,直接GBK->UTF-8;
Unicode编码包含所有字符集,而GBK(GB2312是GBK的一个子集),UTF-8等等都称为多字节集(Multibyte),两个多字节字符集之间的转换首先将源字符集映射到Unicode上,再将Unicode映射到目标多字节字符集上。有一个问题就是源字符集与目标字符集不可能是一一对应的,所以在转换的时候往往会有一个参数表示如果未找到对应的字符的处理情况。另外Unicode中的表示字符用wchar_t,而多字节的字符用char表示(也有多个char表示一个字符)。
windows下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
static int str_utf82gbk(const char * uft8,char *gbk,int maxlen) { int wlen,clen; wchar_t buffer[1024]; /*utf8 to wide char*/ wlen = MultiByteToWideChar(CP_UTF8,0,uft8,-1,NULL,0); if (wlen >= 1024) { return -1; } MultiByteToWideChar(CP_UTF8,0,uft8,-1,buffer,wlen); /*wide char to c string*/ clen = WideCharToMultiByte(CP_ACP,0,buffer,wlen,NULL,0,0,0); if (clen >= maxlen) { return -2; } WideCharToMultiByte(CP_ACP,0,buffer,wlen,gbk,maxlen,0,0); gbk[clen] = '\0'; return clen; } |
C语言中有与WideCharToMultByte对应的接口是wctomb,MultiByteToWideChar对应的接口是mbtowc,但是对应的转化不能将正确的转换UTF-8。具体实现是先将当前语言为源字节集,将源字节集转化成Unicode,然后将语言设置成目标字节集将Unicode转化成目标字节集,具体参见:
setlocale: http://msdn.microsoft.com/en-us/library/aa272906(v=vs.60).aspx
利用第三方库实现,它就是大名鼎鼎的libiconv,有一个值得小心的地方,就是当目标字符集中没有源串中对的字符是可以选择继续还是忽略,所以及在open时会带上参数”//IGNORE”,要不然就遇到这种情况会停止转化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
static int str_utf82gbk(const char * uft8,char *gbk,int maxlen) { iconv_t ic; int clen,last; ic = iconv_open("GBK//IGNORE","UTF-8"); if (ic == (iconv_t)(-1)) { return -1; } clen = strlen(uft8); last = maxlen; iconv(ic,&uft8,&clen,&gbk,&maxlen); last -= maxlen; gbk[0] = '\0'; iconv_close(ic); return last; } |