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