GTK+中文社区(gtk.awaysoft.com)

 找回密码
 马上加入

QQ登录

只需一步,快速开始

查看: 6549|回复: 2

iconv.h 使用笔记

[复制链接]
  • TA的每日心情
    奋斗
    2021-11-19 13:15
  • 签到天数: 20 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2011-2-24 08:25:18 | 显示全部楼层 |阅读模式
    研究了一段时间的iconv.h,终于在查看资料和实践下搞定了iconv这个函数,实现了对包含错误编码的字符串的转码。常见的情况就是,某些字符不属于GBK字符集,而将这个字符串由GBK转到UTF-8的时候就会出错。
    1. int
    2. convert(const char *from, /*要转换的字符集*/
    3.        const char *to, /*要转换到的字符集*/
    4.        char* save, /*输出字符串*/
    5.        int savelen, /*输出字符串缓存长度*/
    6.        char *src, /*源字符串*/
    7.        int srclen) /*源字符串长度*/
    8. {
    9.     iconv_t cd;
    10.     char *inbuf = src;
    11.     char *outbuf = save;
    12.     size_t outbufsize = savelen;
    13.     int status = 0;
    14.     size_t  savesize = 0;
    15.     size_t inbufsize = srclen;
    16.     char* inptr = inbuf;
    17.     size_t insize = inbufsize;
    18.     char* outptr = outbuf;
    19.     size_t outsize = outbufsize;
    20.     cd = iconv_open(to, from);
    21.     iconv(cd,NULL,NULL,NULL,NULL);
    22.     if (inbufsize == 0) {
    23.         status = -1;
    24.         goto done;
    25.     }
    26.     while (insize > 0) {
    27.         size_t res = iconv(cd,&inptr,&insize,&outptr,&outsize);
    28.         if (res == (size_t)(-1)) {
    29.             if (errno == EILSEQ) {
    30.                 inptr ++;
    31.                 status = -3;
    32.             } else if (errno == EINVAL) {
    33.                 break;
    34.             } else if (errno == E2BIG) {
    35.                 status = -5;
    36.                 goto done;
    37.             } else {
    38.                 status = -6;
    39.                 goto done;
    40.             }
    41.         }
    42.     }
    43.     if (outptr != outbuf) {
    44.         int outsize = outptr - outbuf;
    45.         strncpy(save+savesize, outbuf, outsize);
    46.     }
    47.     status = strlen(save);
    48. done:
    49.     iconv_close(cd);
    50.     return status;
    51. }
    复制代码
    使用方法:
    1. gchar *convert(gchar *from)
    2. {
    3.     char *result = g_new(char, strlen(from) * 3 + 1);
    4.     convert2("GBK", "UTF-8", result, strlen(from) * 3 + 1, from, strlen(from));
    5.     if (result != NULL) return result;
    6.     else return "";
    7. }
    复制代码
  • TA的每日心情
    奋斗
    2021-11-19 13:15
  • 签到天数: 20 天

    连续签到: 1 天

    [LV.4]偶尔看看III

     楼主| 发表于 2011-2-24 08:40:19 | 显示全部楼层
    iconv函数族的头文件是iconv.h,使用前需包含之。

         #include<iconv.h>

         iconv函数族有三个函数,原型如下:

         (1)iconv_t iconv_open(const char *tocode,const char *fromcode);

         此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。

         (2)size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);

         此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。

    参数cd必须是由iconv_open函数创建的转换描述符。

    大部分情形是inbuf 不为NULL,*inbuf也不为NULL。这种情况下,iconv函数将以*inbuf起始的多字节序列转换到以*outbuf起始的多字节序列。从*inbuf开始读取,最多*inbytesleft字节,转换后,从*outbuf开始写入,最多*outbytesleft字节。

    iconv函数一次转换一个多字节字符,每次字符转换,*inbuf增加已转换的字节数,*inbytesleft相应地减少已转换的字节数;对应地,*outbuf和*outbytesleft作相应的修改,同时修改cd的转换状态。

    以下四种情况不能完成转换:

    1.输入中含无效的多字节序列。此时,它将errno设置为EILSEQ并返回(size_t)(-1)。*inbuf指向无效序列的最左端。

    2.输入的字节序列已经全部被转换过,也就是*inbytesleft减少至0。此时,iconv返回本次调用中完成转换的数目(可逆的转换不计入)。

    3.输入中以不完整多字节序列作结尾。此时,它将errno设置为EINVAL并返回(size_t)(-1)。*inbuf指向不完整多字节序列的最左端。

    4.输出缓存区没有足够空间来存储下一个字符。此时,它将errno设置为E2BIG并返回(size_t)(-1)。

    另一种情形是inbuf 为NULL或*inbuf为NULL,但*outbuf 不为NULL,*outbuf也不为NULL。这种情况下,iconv函数试图将cd的转换状态设置为初始状态并store a corresponding shift sequence at *outbuf。从*outbuf开始,最多写入*outbytesleft字节。如果输出缓存区没有足够空间来存储这个重置后的序列,他将errno设置为E2BIG并返回(size_t)(-1)。反之,*outbuf增加写入的字节数和*outbytesleft减少写入的字节数。

    第三种情形是inbuf 为NULL或*inbuf为NULL,*outbuf 为NULL或*outbuf为NULL。这种情况下,iconv函数试图将cd的转换状态设置为初始状态。

    返回值

    iconv函数返回本次调用中转换的字符数,可逆的转换不计入。出错时,它将修改errno并返回(size_t)(-1)。

    错误

    除了其它错误以外,出现以下错误:

    E2BIG

    *outbuf没有足够的空间。

    EILSEQ

        输入含无效的多字节序列。

    EINVAL

        输入含不完整多字节序列。

       (3)int iconv_close(iconv_t cd);

        此函数用于关闭转换句柄,释放资源。
  • TA的每日心情
    慵懒
    2013-7-6 15:08
  • 签到天数: 2 天

    连续签到: 2 天

    [LV.1]初来乍到

    发表于 2011-2-27 18:02:39 | 显示全部楼层
    呼呼
    学到了
    *滑块验证:
    您需要登录后才可以回帖 登录 | 马上加入

    本版积分规则

    申请友链|Archiver|小黑屋|手机版|GTK+中文社区 ( 粤ICP备13080851号 )

    我要啦免费统计

    GMT+8, 2024-12-4 02:02 , Processed in 0.025747 second(s), 8 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表