Linux系统下的编码转换


需要使用到的三个函数:

#include <iconv.h>

iconv_t iconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int iconv_close(iconv_t cd);

iconv_open() 为从 fromcode 到 tocode 进行编码转换分配一个适合的转换描述字,并作为返回值返回。
fromcode 和 tocode 的值依赖于系统,在 GNU C 库下,可以使用 iconv --list 命令查看所有被支持的编码。
转换描述字在调用 iconv_close() 释放前能够被 iconv() 无限次调用。
转换描述字包含一个转换状态,调用 iconv_open() 分配后,该状态为初始状态,而调用 iconv() 后,该状态被改变(这意味着转换描述字不能被多线程同时使用),要恢复为初始状态,可以调用 iconv() 时将 inbuf 参数指定为 NULL 。
iconv_open() 调用成功则返回一个新的转换描述字,失败则返回 (iconv_t)-1 并设置 errno 值。发生的错误有:
    EINVAL    从 fromcode 到 tocode 的编码转换不被支持。

iconv() 执行一次编码转换。
参数 cd 必须是调用 iconv_open() 返回的转换描述字。
当 inbuf 和 *inbuf 都不为 NULL 时, iconv() 将从 *inbuf 中读取最多 *inbytesleft 字节的数据转换后写入 *outbuf 中,写入的数据最多 *outbytesleft 字节。
iconv() 进行转换时每次转换一个多字节字符,在循环转换每个字符时,它都增大 *inbuf 并减小 *inbytesleft 读取的字节数,同时也增大 *outbuf 并减小 *outbytesleft 被写入的字节数,并改变包含在转换描述字 cd 中的转换状态。转换在四种情况下将被中止:
    1、要进行转换的多字节字符串是非法的,无法完成转换。这种情况下,将把 errno 设置为 EILSEQ 并返回 (size_t)-1 , *inbuf 将指向非法字符串的开始。
    2、字符串未被全部转换,例如, *inbytesleft 在完全转换前减为 0 。在这种情况下, iconv() 将返回已被转换的字节数。
    3、要进行转换的多字节字符串不完整,比如 UCS-2 编码中一个汉字应该是2个字节,但字符串的最后只有一个字节该字符串就结束了,这种情况下,将设置 errno 为 EINVAL 并返回 (size_t)-1 ,*inbuf 将指向这个不完整字符串的开始。
    4、没有足够的空间存放转换后的数据,这种情况下,将设置 errno 为 E2BIG 并返回 (size_t)-1 。
如果 inbuf 或 *inbuf 为 NULL ,并且 outbuf 和 *outbuf 不为 NULL 时, iconv() 将试着设置转换描述字 cd 的转换状态为初始状态,并在 *outbuf 中记录最多 *outbytesleft 字节的转换序列。但如果没有足够的空间存放改重设序列,将会设置 errno 为 E2BIG 并返回 (size_t)-1 ,否则会增大 *outbuf 和减小 *outbytesleft 被写入的字节数。
如果 inbuf 或 *inbuf 为 NULL ,并且 outbuf 或 *outbuf 也为 NULL 时, iconv() 将只是设置转换描述字 cd 的转换状态为初始状态。
iconv() 调用成功时返回以不可逆方式转换的字符的数目,可逆的转换将不会计算,失败时返回 (size_t)-1 并设置 errno 值。发生的错误有:
    E2BIG     在 *outbuf 中没有足够的空间。
    EILSEG    要进行转换的字符串为非法字符串。
    EINVAL    要进行转换的字符串不完整。
要想得到转换后的数据的字节数,需要用转换开始前的 *outbytesleft 减去转换完成后的 *outbytesleft 。

iconv_close() 释放此前由 iconv_open() 分配的转换描述字。
iconv_close() 调用成功时返回 0 ,失败时返回 -1 并设置 errno 值。

下面这个函数将实现编码的转换:
++++++++++++++++++++++++++++++++++++++++++++++++++

#include <iconv.h>

/************************************************************************************/
/* 功能描述:将 in 中的数据由 fromcode 编码转换为 tocode 编码,并将结果由 out 输出  */
/* 参数说明:                                                                       */
/*           [out]out     转换后存放结果的缓冲区                                    */
/*           [in]outlen   out缓冲区的大小                                           */
/*           [in]in       要进行转换的初始数据                                      */
/*           [in]inlen    in缓冲区的大小                                            */
/*           [in]tocode   目的编码                                                  */
/*           [in]fromcode 源编码                                                    */
/* 返回值:  成功则返回转换后结果的字节数大小;失败则返回 -1 并置 errno 为相应的值  */
/************************************************************************************/
size_t code_conv(char *out, size_t outlen, char *in, size_t inlen, const char *tocode, const char *fromcode)
{
    iconv_t cd;
    size_t olen = outlen;
    
    cd = iconv_open(tocode, fromcode);
    if (cd == (iconv_t)-1) return -1;
    
    if (iconv(cd, &in, &inlen, &out, &outlen) == (size_t)-1)
        return -1;
    
    iconv_close(cd);
    
    return olen - outlen;
}

++++++++++++++++++++++++++++++++++++++++++++++++++

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值