123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- // 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;
- }
|