// stdafx.cpp : 只包括标准包含文件的源文件 // iconvtest.pch 将作为预编译头 // stdafx.obj 将包含预编译类型信息 #include "stdafx.h" /* iconv()将返回(size_t)-1并设置errno来指示错误。 errno值如下: [EILSEQ] 输入转换由于不属于输入代码集的输入字节而停止。 [E2BIG] 由于输出缓冲区空间不足,输入转换停止。 [EINVAL] 由于输入缓冲区末尾的字符或移位序列不完整,导致输入转换停止。 如果出现以下情况,iconv()函数可能失败: [EBADF] 该CD的说法是不是有效的打开转换描述。 */ int ChangeCode( const char* pFromCode, const char* pToCode, const char* pInBuf, size_t* iInLen, char* pOutBuf, size_t* iOutLen) { int iRet; // 打开字符集转换; iconv_t hIconv = iconv_open(pToCode, pFromCode); if (-1 == (int)hIconv) { return -1;//打开失败,可能不支持的字符集 } //开始转换 iRet = iconv(hIconv, (const char**)(&pInBuf), iInLen, (char**)(&pOutBuf), iOutLen); //关闭字符集转换 iconv_close(hIconv); return iRet; } /************************************************************************/ /* 函数:[1/22/2018 Home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ std::string convert(const char *from, const char* to, const char* inbuf, const size_t &inbufsize) { int iconv_ret = 0; // 打开字符集转换; iconv_t hIconv = iconv_open(to, from); if (-1 == (int)hIconv) return "";//打开失败,可能不支持的字符集 size_t insize = inbufsize; std::string strout; // 循环利用; size_t outsize = 512; // 513多一位用做字符结束符; char out[513] = { 0 }; while (insize > 0) { outsize = 512; memset(out, 0, outsize); // out地址保存不变,以便重复使用; char *p = out; // 开始转换; iconv_ret = iconv(hIconv, (const char**)(&inbuf), &insize, &p, &outsize); if (((iconv_ret == (size_t)-1) && (E2BIG == errno)) || (iconv_ret != (size_t)-1)) { // out和p地址不同, p-out指针相减得到长度; //strout.append(out, p - out); strout.insert(strout.size(), out, p - out); } } //关闭字符集转换 iconv_close(hIconv); return strout; } std::string convertEx(const char *from, const char* to, const char* inbuf, const size_t &inbufsize) { int iconv_ret = 0; // 打开字符集转换; iconv_t hIconv = iconv_open(to, from); if (-1 == (int)hIconv) return "";//打开失败,可能不支持的字符集 int status = 0; iconv(hIconv, NULL, NULL, NULL, NULL); size_t insize = inbufsize; std::string strout; // 循环利用; size_t outsize = 512; // 513多一位用做字符结束符; char out[513] = { 0 }; while (insize > 0) { outsize = 512; memset(out, 0, outsize); // out地址保存不变,以便重复使用; char *p = out; // 开始转换; iconv_ret = iconv(hIconv, (const char**)(&inbuf), &insize, &p, &outsize); if (out != p) { int saved_errno = errno; strout.insert(strout.size(), out, p - out); errno = saved_errno; } if (iconv_ret == (size_t)(-1)) { if (errno == EILSEQ) {// 输入中遇到无效的多字节序列; int one = 1; // 非法序列丢弃并继续; iconvctl(hIconv, ICONV_SET_DISCARD_ILSEQ, &one); status = -3; } else if (errno == EINVAL) {// 输入中遇到了一个不完整的多字节序列; if (inbufsize == 0) { status = -4; goto done; } else { break; } } else if (errno == E2BIG) {// *outbuf没有足够的空间; status = -5; //goto done; } else { status = -6; goto done; } } /*if (((iconv_ret == (size_t)-1) && (E2BIG == errno)) || (iconv_ret != (size_t)-1)) { // out和p地址不同, p-out指针相减得到长度; //strout.append(out, p - out); strout.insert(strout.size(), out, p - out); }*/ } done: //关闭字符集转换 iconv_close(hIconv); return strout; } /************************************************************************/ /* 函数:[1/21/2018 Jeff]; /* 描述:对字符串进行语言编码转换; /* 参数:; /* [IN] from:原始编码,比如"GB2312",的按照iconv支持的写; /* [IN] to:转换的目的编码; /* [IN] save:转换后的数据保存到这个指针里,需要在外部分配内存; /* [IN] savelen:存储转换后数据的内存大小; /* [OUT] src:原始需要转换的字符串; /* [OUT] srclen:原始字符串长度; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ int convert(const char *from, const char *to, char* save, int savelen, char *src, int srclen) { iconv_t cd; char *inbuf = src; char *outbuf = save; size_t outbufsize = savelen; int status = 0; size_t savesize = 0; size_t inbufsize = srclen; const char* inptr = inbuf; size_t insize = inbufsize; char* outptr = outbuf; size_t outsize = outbufsize; cd = iconv_open(to, from); iconv(cd, NULL, NULL, NULL, NULL); if (inbufsize == 0) { status = -1; goto done; } while (insize > 0) { size_t res = iconv(cd, (const char**)&inptr, &insize, &outptr, &outsize); if (outptr != outbuf) { int saved_errno = errno; int outsize = outptr - outbuf; strncpy(save + savesize, outbuf, outsize); errno = saved_errno; } if (res == (size_t)(-1)) { if (errno == EILSEQ) { int one = 1; iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one); status = -3; } else if (errno == EINVAL) { if (inbufsize == 0) { status = -4; goto done; } else { break; } } else if (errno == E2BIG) { status = -5; goto done; } else { status = -6; goto done; } } } status = strlen(save); done: iconv_close(cd); return status; }