在C语言里用iconv转换字符编码(UTF8->GB18030)

这段代码的作用是从一个文本文件里读出字符串,转换一下编码,再写入另一个文件

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <memory.h>
 4 #include <iconv.h>
 5 
 6 const int LENGTH = 80;
 7 const int BUFSZ = LENGTH * 2;
 8 
 9 int print_n_str(const char *str, long len)
10 {
11     char buf[BUFSZ];
12     memset(buf, 0, BUFSZ);
13     memcpy(buf, str, len);
14     return printf("in:[%s](%ld)\n", buf, len);
15 }
16 
17 int print_hex_str(const char *str, long len)
18 {
19     printf("out:[");
20     for (int i = 0; i < len; i++)
21     {
22         printf("%%%02x", (unsigned char)str[i]);
23     }
24     printf("](%ld)\n", len);
25     return 0;
26 }
27 
28 int main()
29 {
30     iconv_t icv = iconv_open("GB18030", "UTF-8");
31     FILE *in = fopen("in.txt", "r");
32     FILE *out = fopen("out.txt", "w");
33     
34     char in_line[BUFSZ];
35     char out_line[BUFSZ];
36     size_t left = 0;
37     while (!feof(in))
38     {
39         memset(in_line + left, 0, BUFSZ - left);
40         fread(in_line + left, 1, LENGTH, in);
41         left = strlen(in_line);
42         
43         char *inbuf = in_line;
44         char *outbuf = out_line;
45         size_t inleft = left;
46         size_t outleft = BUFSZ;
47         iconv(icv, &inbuf, &inleft, &outbuf, &outleft);
48         
49         size_t ilen = left - inleft;
50         print_n_str(in_line, ilen);
51         if (!inleft)
52         {
53             memmove(in_line, in_line + ilen, inleft);
54         }
55         left = inleft;
56         
57         size_t olen = BUFSZ - outleft;
58         print_hex_str(out_line, olen);
59         fwrite(out_line, 1, olen, out);
60     }
61     fclose(in);
62     fclose(out);
63     iconv_close(icv);
64     return 0;
65 }

但实际上,这段代码有好几个坑

1 iconv_t iconv_open (const char* tocode, const char* fromcode);
2 
3 size_t iconv (iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
4 
5 nt iconv_close (iconv_t cd)

1.函数1,两个参数是dest, src很容易无意中写错了,然后还发现不了

2.函数2,后面四个参数都是会变的,不要把原来的变量傻乎乎传进去到时候就找不回来了

3.函数2,有些时候我们的inbuf里不一定是完整的utf8字符串,可能有一些是被截断的“半个汉字”,此时iconv()会返回-1,并且会有errno,但是其实在应用层,这未必是错误,而是需要处理的情况。此时就需要inbytesleft参数,这个参数存的是剩下没处理的数据。

4.函数2,outbyetsleft指的是outbuf剩余的空闲空间,不要把它当成输出字符串的长度

转载于:https://www.cnblogs.com/sixue1999/p/8397029.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值