stdafx.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // stdafx.cpp : 只包括标准包含文件的源文件
  2. // iconvtest.pch 将作为预编译头
  3. // stdafx.obj 将包含预编译类型信息
  4. #include "stdafx.h"
  5. /*
  6. iconv()将返回(size_t)-1并设置errno来指示错误。
  7. errno值如下:
  8. [EILSEQ]
  9. 输入转换由于不属于输入代码集的输入字节而停止。
  10. [E2BIG]
  11. 由于输出缓冲区空间不足,输入转换停止。
  12. [EINVAL]
  13. 由于输入缓冲区末尾的字符或移位序列不完整,导致输入转换停止。
  14. 如果出现以下情况,iconv()函数可能失败:
  15. [EBADF]
  16. 该CD的说法是不是有效的打开转换描述。
  17. */
  18. int ChangeCode(
  19. const char* pFromCode,
  20. const char* pToCode,
  21. const char* pInBuf,
  22. size_t* iInLen,
  23. char* pOutBuf,
  24. size_t* iOutLen)
  25. {
  26. int iRet;
  27. // 打开字符集转换;
  28. iconv_t hIconv = iconv_open(pToCode, pFromCode);
  29. if (-1 == (int)hIconv)
  30. {
  31. return -1;//打开失败,可能不支持的字符集
  32. }
  33. //开始转换
  34. iRet = iconv(hIconv, (const char**)(&pInBuf), iInLen, (char**)(&pOutBuf), iOutLen);
  35. //关闭字符集转换
  36. iconv_close(hIconv);
  37. return iRet;
  38. }
  39. /************************************************************************/
  40. /* 函数:[1/22/2018 Home];
  41. /* 描述:;
  42. /* 参数:;
  43. /* [IN] :;
  44. /* [OUT] :;
  45. /* [IN/OUT] :;
  46. /* 返回:void;
  47. /* 注意:;
  48. /* 示例:;
  49. /*
  50. /* 修改:;
  51. /* 日期:;
  52. /* 内容:;
  53. /************************************************************************/
  54. std::string convert(const char *from, const char* to, const char* inbuf, const size_t &inbufsize)
  55. {
  56. int iconv_ret = 0;
  57. // 打开字符集转换;
  58. iconv_t hIconv = iconv_open(to, from);
  59. if (-1 == (int)hIconv)
  60. return "";//打开失败,可能不支持的字符集
  61. size_t insize = inbufsize;
  62. std::string strout;
  63. // 循环利用;
  64. size_t outsize = 512;
  65. // 513多一位用做字符结束符;
  66. char out[513] = { 0 };
  67. while (insize > 0)
  68. {
  69. outsize = 512;
  70. memset(out, 0, outsize);
  71. // out地址保存不变,以便重复使用;
  72. char *p = out;
  73. // 开始转换;
  74. iconv_ret = iconv(hIconv, (const char**)(&inbuf), &insize, &p, &outsize);
  75. if (((iconv_ret == (size_t)-1) && (E2BIG == errno)) || (iconv_ret != (size_t)-1))
  76. {
  77. // out和p地址不同, p-out指针相减得到长度;
  78. //strout.append(out, p - out);
  79. strout.insert(strout.size(), out, p - out);
  80. }
  81. }
  82. //关闭字符集转换
  83. iconv_close(hIconv);
  84. return strout;
  85. }
  86. std::string convertEx(const char *from, const char* to, const char* inbuf, const size_t &inbufsize)
  87. {
  88. int iconv_ret = 0;
  89. // 打开字符集转换;
  90. iconv_t hIconv = iconv_open(to, from);
  91. if (-1 == (int)hIconv)
  92. return "";//打开失败,可能不支持的字符集
  93. int status = 0;
  94. iconv(hIconv, NULL, NULL, NULL, NULL);
  95. size_t insize = inbufsize;
  96. std::string strout;
  97. // 循环利用;
  98. size_t outsize = 512;
  99. // 513多一位用做字符结束符;
  100. char out[513] = { 0 };
  101. while (insize > 0)
  102. {
  103. outsize = 512;
  104. memset(out, 0, outsize);
  105. // out地址保存不变,以便重复使用;
  106. char *p = out;
  107. // 开始转换;
  108. iconv_ret = iconv(hIconv, (const char**)(&inbuf), &insize, &p, &outsize);
  109. if (out != p)
  110. {
  111. int saved_errno = errno;
  112. strout.insert(strout.size(), out, p - out);
  113. errno = saved_errno;
  114. }
  115. if (iconv_ret == (size_t)(-1))
  116. {
  117. if (errno == EILSEQ)
  118. {// 输入中遇到无效的多字节序列;
  119. int one = 1;
  120. // 非法序列丢弃并继续;
  121. iconvctl(hIconv, ICONV_SET_DISCARD_ILSEQ, &one);
  122. status = -3;
  123. }
  124. else if (errno == EINVAL)
  125. {// 输入中遇到了一个不完整的多字节序列;
  126. if (inbufsize == 0)
  127. {
  128. status = -4;
  129. goto done;
  130. }
  131. else
  132. {
  133. break;
  134. }
  135. }
  136. else if (errno == E2BIG)
  137. {// *outbuf没有足够的空间;
  138. status = -5;
  139. //goto done;
  140. }
  141. else {
  142. status = -6;
  143. goto done;
  144. }
  145. }
  146. /*if (((iconv_ret == (size_t)-1) && (E2BIG == errno)) || (iconv_ret != (size_t)-1))
  147. {
  148. // out和p地址不同, p-out指针相减得到长度;
  149. //strout.append(out, p - out);
  150. strout.insert(strout.size(), out, p - out);
  151. }*/
  152. }
  153. done:
  154. //关闭字符集转换
  155. iconv_close(hIconv);
  156. return strout;
  157. }
  158. /************************************************************************/
  159. /* 函数:[1/21/2018 Jeff];
  160. /* 描述:对字符串进行语言编码转换;
  161. /* 参数:;
  162. /* [IN] from:原始编码,比如"GB2312",的按照iconv支持的写;
  163. /* [IN] to:转换的目的编码;
  164. /* [IN] save:转换后的数据保存到这个指针里,需要在外部分配内存;
  165. /* [IN] savelen:存储转换后数据的内存大小;
  166. /* [OUT] src:原始需要转换的字符串;
  167. /* [OUT] srclen:原始字符串长度;
  168. /* 返回:void;
  169. /* 注意:;
  170. /* 示例:;
  171. /*
  172. /* 修改:;
  173. /* 日期:;
  174. /* 内容:;
  175. /************************************************************************/
  176. int convert(const char *from, const char *to, char* save, int savelen, char *src, int srclen)
  177. {
  178. iconv_t cd;
  179. char *inbuf = src;
  180. char *outbuf = save;
  181. size_t outbufsize = savelen;
  182. int status = 0;
  183. size_t savesize = 0;
  184. size_t inbufsize = srclen;
  185. const char* inptr = inbuf;
  186. size_t insize = inbufsize;
  187. char* outptr = outbuf;
  188. size_t outsize = outbufsize;
  189. cd = iconv_open(to, from);
  190. iconv(cd, NULL, NULL, NULL, NULL);
  191. if (inbufsize == 0) {
  192. status = -1;
  193. goto done;
  194. }
  195. while (insize > 0)
  196. {
  197. size_t res = iconv(cd, (const char**)&inptr, &insize, &outptr, &outsize);
  198. if (outptr != outbuf)
  199. {
  200. int saved_errno = errno;
  201. int outsize = outptr - outbuf;
  202. strncpy(save + savesize, outbuf, outsize);
  203. errno = saved_errno;
  204. }
  205. if (res == (size_t)(-1))
  206. {
  207. if (errno == EILSEQ)
  208. {
  209. int one = 1;
  210. iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one);
  211. status = -3;
  212. }
  213. else if (errno == EINVAL)
  214. {
  215. if (inbufsize == 0)
  216. {
  217. status = -4;
  218. goto done;
  219. }
  220. else
  221. {
  222. break;
  223. }
  224. }
  225. else if (errno == E2BIG)
  226. {
  227. status = -5;
  228. goto done;
  229. }
  230. else {
  231. status = -6;
  232. goto done;
  233. }
  234. }
  235. }
  236. status = strlen(save);
  237. done:
  238. iconv_close(cd);
  239. return status;
  240. }