c++ 中使用libxml中操作中文字符的时候出现各种写入出错、读出乱码等问题,经过半天的折腾,写个笔记:
首先明确下边几个事情就很容易知道问题在哪了:
1、cpp 文件中出现的中文字符串常量都会被保存成ansi格式,而gb2312格式可以理解为ansi格式的一个子集。(在中文和日文操作系统里生成的(txt和xml)文件的编码虽然都是ansi,但是,在简体中文系统下,ansi 编码代表 GB2312 编码,在日文操作系统下,ansi 编码代表 JIS 编码。不同 ansi 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ansi 编码的文本中。)
2、libxml接口的所有参数输入都会被当成utf-8编码格式的,输出也是。
3、假如传入到libxm接口中的字符是非utf-8编码格式,例如gb2312的,假如字符串中含有中文,将有可能使得xmlSaveFormatFileEnc()返回 -1,导致保存失败。
4、获取到的中文是为utf-8格式的,假如不转成其他格式而直接显示出来的话,可能会出现乱码。
下边了是实现utf-8 和 gb2312 的编码转换函数实现:
#include "iconv.h"
#include <string.h>
//代码转换:从一种编码转为另一种编码
int code_convert(char* from_charset, char* to_charset, const char* inbuf,
int inlen, char* outbuf, int outlen)
{
iconv_t cd;
const char** pin = &inbuf;
char** pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if(cd == 0) return -1;
memset(outbuf,0,outlen);
if(iconv(cd,(const char**)pin,(unsigned int *)&inlen,pout,(unsigned int*)&outlen) == -1)return -1;
iconv_close(cd);
return 0;
}
//UNICODE码转为GB2312码
string u2g(const string sIn)
{
if (sIn.empty())
{
return "";
}
const char *inbuf = sIn.c_str();
int nOutLen = 2 * strlen(inbuf) - 1;
char* szOut = (char*)malloc(nOutLen);
if (-1 == code_convert("utf-8","gb2312",inbuf,strlen(inbuf),szOut,nOutLen))
{
free(szOut);
szOut = NULL;
}
string sRet = szOut;
free(szOut);
return sRet;
}
//GB2312码转为UNICODE码
string g2u(const string sIn)
{
if (sIn.empty())
{
return "";
}
const char *inbuf = sIn.c_str();
int nOutLen = 2 * strlen(inbuf) - 1;
char* szOut = (char*)malloc(nOutLen);
if (-1 == code_convert("gb2312","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))
{
free(szOut);
szOut = NULL;
}
string sRet = szOut;
free(szOut);
return sRet;
}
原文地址:http://blog.csdn.net/yangyihongyangjiying/article/details/45894315