最近使用tinyxml 做些配置文件操作,碰到中文显示为乱码的问题,本人使用VC6,网上查了资料,默认使用的是MBSC,所以本身使用汉字是没有问题,但我的xml文件是保存为utf-8编码,下面代码的工作就是 utf-8转unicode,然后unicode转MBSC,前面的代码是别人写的,我加了两个函数UTF8ToUnicode_all和GetMBSC,因为我使用MFC环境,直接能一步转成CString当然最好了。
顺便贴上一点资料,有助于理解,关于utf-8的:
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。
如表:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
因此UTF-8中可以用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去那些控制位(每字节开头的10等),这些x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。
实际将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数。
因此那些基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一个字节的UTF-8编码(7个二进制位)便可以表示
//
int GetNo(char ch)
{
int i = 0;
while (ch & 0x80)
{
++i;
ch <<= 1;
}
return i;
}
void UTF8ToUnicode(char *pUnicode, const char *pUtf8, int nBytes)
{
if ( 0 == nBytes ) { *pUnicode = *pUtf8;}
else if ( nBytes == 3 )
{
*pUnicode = (*pUtf8) & 0xf;
(*pUnicode) <<= 4;
pUtf8++;
char tt = (*pUtf8) & 0x3f;
char t = (tt >> 2) & 0xf;
(*pUnicode) |= t;
char *W1 = pUnicode;
char W2 = *W1;
++pUnicode;
*pUnicode = (tt & 0x3) << 6;
pUtf8++;
(*pUnicode ) |= (*pUtf8 & 0x3f);
*W1 = *pUnicode;
*pUnicode = W2;
}
++pUnicode;
*pUnicode = 0;
}
void UTF8ToUnicode_all(char *pUnicode, const char *pUtf8 )
{
int count = strlen( pUtf8 );
for(int i=0; i<count; )
{
char ch = pUtf8[i];
int type = GetNo(ch);
if( type == 0 )
{
char unicode[12]={0};
UTF8ToUnicode( unicode, &pUtf8[i],0);
strcat( pUnicode, unicode );
i++;
}
else if( type == 3 )
{
char unicode[12]={0};
UTF8ToUnicode( unicode,&pUtf8[i],3 );
strcat( pUnicode, unicode );
i += 3;
}
else
{
ASSERT(FALSE);
}
}
}
void UnicodeToMBSC(char* pOut, WCHAR* uData)
{
int size_need = WideCharToMultiByte(CP_ACP,NULL,uData,wcslen(uData),pOut,0,NULL,NULL);
WideCharToMultiByte(CP_ACP,NULL,uData,wcslen(uData),pOut,size_need,NULL,NULL);
}
CString GetMBSC( const char* text )
{
ASSERT( strlen(text) < 1024 );
char unicode_buf[1024] ={0};
UTF8ToUnicode_all( unicode_buf, text );
char mbsc_buf[1024] ={0};
UnicodeToMBSC(mbsc_buf, (WCHAR*)unicode_buf);
return CString(mbsc_buf);
}
代码比较粗糙,有心人可以改改,tinyxml保存成utf8时也会有些问题,研究好了再来贴,
我已经放弃了保存成utf-8了,因为utf-8转成unicode,可以,unicode转mbsc又有难题,特别是即有中文又有英文的情况。我最后直接写和读就当文本读写一样,中文和英文都能正常显示,只是在浏览器里打开有错误,但这对于我存储数据没有影响。VC默认使用MBSC,我想如果是默认是unicode,会不会就没有这些问题了