Linux下编码转换解决方案

 
Linux下编码转换解决方案
2009年04月26日 星期日 上午 03:21

Text

  Linux下支持多种字符编码,正是因为这样,所以经常遇到编码转换的问题。我在做ftp爬虫的时候就遇到这样的问题。假如我们要搜索某个ftp服务器上的数据,那么就必须获取对方的服务器字符编码信息:一方面为了能够把所有信息统一编码入库;另一方面,能够为用户提供有效的文件链接地址。那么我们该如何获取这个未知的字符编码信息呢?通过基于系统提供的iconv函数进行不断“尝试”,直到找到正确的编码为止。

  在我们的应用中,常见的字符编码是一定的,因此我们可以通过尝试有限的几种可能的编码找出字符的原编码。这样我们就可以在不知道原编码的情况下,进行编码转换了。另外,如果在第一次尝试正确以后就记住原编码的话,我们在以后的编码转化中就可以直接进行编码转化了。因此,在
CodeConvert.h里头,我定义了四种不同的实现:需要指定原编码和目标编码,返回原编码编号,在不知道原编码的情况下转换,在知道原编码的情况下转换。这样基本就可以满足需求拉。

Code

[1] CodeConvert.h

#define LOCAL_ENCODE "gb2312"

int code_convert(char *from_code, char *to_code, char *from, char *to);
int code_convert_to(char *to_code, char *from, char *to);
char *c2localencode(char *from, char *to);
char *c2localencoders(char *from, char *to, int *source_code);


[2] CodeConvert.c

/* CodeConvert.c -- code convert function
* Designed by falcon, 2006-9-16 , Email: zhangjinw[at]gmail.com
* */


#include <iconv.h>
#include <string.h>
#include <errno.h>
#include "CodeConvert.h"

#ifndef BUF_MAX_LEN
#define BUF_MAX_LEN 1024    /*you must set the sizeofbuf_temp larger then BUF_MAX_LEN*/
#endif

char *code_knowned[] = {    /*define you own codes here*/
/*0*/    "ASCII",
/*1*/    "gb2312",
/*2*/    "utf8",
/*3*/    "gbk"
};

                /*code from one to another*/
int
code_convert(char *from_code, char *to_code, char *from, char *to)    
{
    static iconv_t cd;
    static char *tptr, *fptr;
    static size_t ileft, oleft, ret;

     tptr = fptr =NULL;
    
    if(from == NULL || to == NULL) return -1;

     cd = iconv_open((const char *)to_code, (const char *)from_code);
    if (cd == (iconv_t)-1) {
        return -1;
    }

     ileft = strlen(from);
     fptr = from;
     for (;;) {
         tptr = to;
         oleft = BUF_MAX_LEN;

         ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
        if (ret != (size_t)-1) {
             break;
         }
    
        if (errno == EINVAL) {
            (void) memmove(from, fptr, ileft);
            (void) iconv(cd, &fptr, &ileft, &tptr, &oleft);
            (void) iconv_close(cd);
            return 1;
        } else if (errno == E2BIG) {
            continue;
        } else if (errno == EILSEQ) {
            (void) iconv(cd, &fptr, &ileft, &tptr, &oleft);
             (void) iconv_close(cd);
            return 1;
        } else if (errno == EBADF) {
             return -1;
        } else {
            return -1;
        }
    }

    (void) iconv(cd, &fptr, &ileft, &tptr, &oleft);
    (void) iconv_close(cd);
   return 0;
}
                    
/*convert any code to the code you want,return the source code num*/
int
code_convert_to(char *to_code, char *from, char *to)
{
    static int i, ret, code_knowned_num;
    
     code_knowned_num = sizeof(code_knowned) / sizeof(code_knowned[0]);
    for(i = 0; i < code_knowned_num; i++)
    {
         ret = code_convert( code_knowned[i], to_code, from, to);
        if (ret == 0)    return i;
        else if (ret == 1)    continue;
        else{
            return -1;
        }
    }
}

/*convert any code to utf8*/
char *
c2localencode(char *from, char *to)
{
    static int ret;

     ret = code_convert_to(LOCAL_ENCODE, from, to);

    if (ret == -1)
    {
        return NULL;
    }
    else
    {    
        return to;
    }    
}

char *
c2localencoders(char *from, char *to, int *source_code)
{
    static int ret;

     ret = code_convert_to(LOCAL_ENCODE, from, to);

    if (ret == -1)
    {
        return NULL;
    }
    else
    {    
        *source_code = ret;
        return to;
    }    
}


[3] test_CodeConvert.c

#include "CodeConvert.h"
#include <stdio.h>
#include <string.h>

int main()
{
        char* from="爱情";
        char to[20];

        memset(to, 0, 20);
        printf("%s\n", c2localencode(from, to));

        return 0;
}


Demo

  在上面的 CodeConvert.h代码里头,我把本地编码设置成gb2312。通过调整终端的字符编码为gb2312,我们就可以看到正确的编码输出结果。

shell> gcc -o test_CodeConvert test_CodeConvert.c CodeConvert.c
shell> ./test_CodeConvert
爱情
  

Extension

  我把上面的代码应用到了ftp搜索引擎里头,在爬虫工作的时候,记住某个ftp服务器的字符编码,并存入数据库中,之后再爬取该ftp服务器的数据时,就从数据库从获取该服务器的字符编码信息,直接进行编码转化,从而提高了工作效率。另外,在为用户提供搜索接口的时候,同样可以从数据库中获取对应服务器的字符编码信息,为用户返回有效的文件链接地址。

Reference

[1]  manpage for iconv(3c)
[2] http://oss.lzu.edu.cn/blog/blog.php?do_showone/tid_669.html

Download

文件:codeconvert-0.1.tar.gz
大小:1KB
下载:下载

有删减。
  原文地址:http://oss.lzu.edu.cn/blog/blog.php?do_showone/tid_669.html


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值