字符集和字符编码
很多相关文章都模糊了字符集和字符编码的概念。字符集和字符编码(Charset & Encoding)这篇文章非常赞,简明扼要,介绍了两者的概念以及常用字符集和字符编码。
另外,关于所谓 ANSI 编码。ANSI(American National Standards Institute,ANSI)是负责制定美国国家标准的非营利组织。它针对不同的地区与国家,定义了一系列的支持不同语言字符集的代码页。所以各国字符集和字符编码被 统称为 ANSI。
ANSI 不同的语言使用不同的字符集和字符编码,所以跨语言不能通用,会出现乱码。ANSI 没有很明显的特征 Xcode 或一些文本编辑器打开可能乱码。
最通用的编码是 UTF-8 without BOM。Windows 里的软件一般都默认有 BOM,而其它系统都默认没有 BOM。Visual Studio 下可以在 文件 -> 高级保存选项
更改编码。
iconv 的一个类型,三个函数
数据类型:
iconv_t
这是 iconv 中定义的一个抽象类型,不要去对它做任何假设,因为它必须完全地是不明确的。
当使用iconv
函数时,该类型的对象会被赋值为 转换 的句柄。对象本身不需要释放,但是句柄所表示的 转换 需要释放。函数:
iconv_t iconv_open (const char* tocode, const char* fromcode);
转换开始前必须使用该函数初始化。两个参数分别是转换的目标字符集和需要转换的源字符集。如果转换可以执行,返回一个句柄;否则返回 -1。函数:
size_t iconv (iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
该函数根据cd
将 输入缓冲中的文本进行转换,并将结果保存于输出缓冲中。*outbuf
指向一个至少有*outbytesleft
个字节空间来保存结果的缓冲区的开始处。函数:
int iconv_close (iconv_t cd);
释放与句柄cd
相关的全部资源,当然前提是正确调用了iconv_open
函数。
进一步阅读:Generic Character Set Conversion Interface
gbk -> utf-8 转换示例
bool Chinese::iconvConvert(const char* from_charset, const char* to_charset, char* inbuf, int inlen, char* outbuf, int outlen)
{
iconv_t cd=iconv_open(to_charset, from_charset);
if(cd==0)
return false;
char** pin=&inbuf;
char** pout=&outbuf;
memset(outbuf, 0, outlen);
size_t ret=iconv(cd, pin, (size_t*)&inlen, pout, (size_t*)&outlen);
iconv_close(cd);
return ret==(size_t)(-1)? false: true;
}
string Chinese::iconvGbkToUtf8(const string& str)
{
string inStr = str;
char* textIn = (char*)inStr.c_str();
int inLen = str.length();
int outLen = inLen * 2 + 1;
char* textOut = (char*)malloc(outLen);
bool ret = false;
if (textOut)
ret = iconvConvert("gbk", "utf-8", textIn, inLen, textOut, outLen);
string strOut = ret ? string(textOut) : string();
free(textOut);
return strOut;
}