Unicode编码转化介绍

类别:编程语言 点击:0 评论:0 推荐:
1        简介 1.1   目的

本文档介绍了在WIN32和LINUX等平台下的各种编码之间的转化方法。

1.2   概述

ANSI C定义了统一的编码转化函数setlocale,mbstowcs,wcstombs,但这些函数在WIN32平台上实现了,却未在LINUX平台上实现,在linux平台上实现编码转化需要调用iconv_open, iconv, iconv_close函数。

2        WIN32平台下的编码转化 2.1   ANSI C方法

WIN32平台下,ANSI的setlocale,wcstombs,mbstowcs, L’’str”等函数运行正常。其中setlocale后面的参数可以是’”.ACP”,””, NULL, “C”, “chinese”,

“Chinese_People's Republic of China.936”等。一般应使用”.ACP”,代表操作系统当前使用的代码页,NULL,””,”C”代表操作系统的缺省代码页,请注意两者之间的细微区别。 L”str”代表str的UnicodeLittle编码。

void testBMPStrToStr(const char* pc_locale, const wchar_t* pc_wnm,

                                                char* pc_data, int nPCDataLen)

{

         char* pclocale = setlocale(LC_CTYPE, pc_locale);

         cout << pc_locale << " locale=" << (pclocale==NULL?"FALSE":pclocale) << endl;

        

         memset(pc_data, 0, nPCDataLen);

         int n = sprintf(pc_data, "%ls", pc_wnm);

         pc_data[n]=0; cout << "sprintf convert=" << pc_data << endl;

         memset(pc_data, 0, nPCDataLen);

         n = wcstombs(pc_data, pc_wnm, nPCDataLen);

         pc_data[n]=0; cout << "wcstombs convert=" << pc_data << endl;

}

2.2   MultiByteToWideChar和WideCharToMultiByte方法

WIN32平台自己提供了两个编码码转化函数MultiByteToWideChar和

WideCharToMultiByte。两个不同的编码页间的转化需要通过UnicodeLittle编码来中转。例如:

bool ACP2UTF8(const HGChar* pc_acp, HGCharArray& chArrUTF8)

{

    HGCharArray chArrUnicode;   

    int nLen = 2*strlen(pc_acp)+1;

    chArrUTF8.resize(nLen+1);

    chArrUnicode.resize(nLen+1);

  

         if( 0== MultiByteToWideChar( CP_ACP, 0, pc_acp, -1, (LPWSTR)&chArrUnicode[0], nLen) )

                            return false;

if( 0!= WideCharToMultiByte( CP_UTF8, 0, (LPCWSTR)&chArrUnicode[0], -1,

&chArrUTF8[0], nLen, NULL, NULL ) )

                            return true; 

    return false;

}

3        linux平台下的编码转化 3.1   ANSI C方法

linux下的ANSI C 方法setlocale,mbstowcs,wcstombs不可用,会出错。又 L”str”也不是将后面的str转化成unicode编码,例如 L“福建省运营根CA”在RedHat下的结果是 B8 00 00 00 A3 00 00 00 BD 00 00 00 A8 00 00 00 CA 00 00 00 A1 00 00 00 D4 00 00 00 CB 00 00 00 D3 00 00 00 AA 00 00 00 B8 00 00 00 F9 00 00 00 43 00 00 00 41 00 00 00 00 00 00 00,CYGWIN下的结果是 B8 00 A3 00 BD 00  A8 00  CA 00 A1 00 D4 00 CB 00 D3 00 AA 00 B8 00 F9 00 43 00 41 00 00 00,但其实际的UnicodeLittile编码是8F 79 FA 5E 01 77 D0 8F 25 84 39 68 43 00 41 00 00 00。

3.2   iconv方法

linux下主要使用iconv相关方法来转化各个编码。其基本调用方式是,iconv_open, iconv, iconv_close 。其中iconv_open的两个参数代表需要互相转化的两个编码页,iconv函数代表编码转化,注意其后面的四个参数都是可变的,返回时依次表示,已转化完成的最后一个字节的下一个字节,未转化的字节数,缓冲区的下一字节,剩余的缓冲区字节数。例如:

int testUnicode()

{

         #ifdef __linux__

                   #define ICONV_CONST

         #else

                   #define ICONV_CONST const

         #endif

         char inbuf[HG_LARGE_STR_LEN]="福建省运营根CA";

         char outbuf[HG_LARGE_STR_LEN];

         ICONV_CONST char* pin = inbuf;

         char* pout = outbuf;

 

         size_t inleft = strlen(pin)+1;

         size_t outleft = HG_LARGE_STR_LEN;

         iconv_t cd = iconv_open("UNICODEBIG","CN-GB");

         if((int)cd == -1)

                   return -1;

         if((int)iconv(cd, &pin, &inleft, &pout, &outleft) == -1)

                   return -1;

         iconv_close(cd);

 

         MEM_OBJECT::binaryToASCII((HGBYTE*)outbuf, HG_LARGE_STR_LEN-outleft, inbuf);

         cout << "actual wcs=" << inbuf << endl;  

 

         return 0;

}

其中iconv_open函数的两个参数可以使用命令iconv –l >codePage.txt看到。

4        CYGWIN平台下的编码转化

CYGWIN平台下的编码转化与linux平台下的编码转化一致,不过iconv*函数在库libiconv.a 中。

5        其它平台下的编码转化

其它solaris,aix平台下的编码转化未曾研究,但应与linux平台下的转化相类似。

本文地址:http://com.8s8s.com/it/it26275.htm