最近在做一个类似垂直下载的爬虫系统。下载之后有个解析模块,解析之后要求编码一致的向后传入索引,便遇到了编码转换问题。

1. 编码的识别

推荐使用 libchardet, 可以在这个页面下载,使用说明就算了,直接读头文件吧。

这是一个简单的示例,嘿嘿。

//#include "chardetect.h"

//char out_encode[CHARDET_MAX_ENCODING_NAME]

char* EncodeUtil::GetLocalEncoding(constchar* in_str, unsignedintstr_len,char* out_encode){

chardet_t chardect=NULL;

if(chardet_create(&chardect)==CHARDET_RESULT_OK){

if(chardet_handle_data(chardect, in_str, (unsignedint)str_len) == CHARDET_RESULT_OK)

if(chardet_data_end(chardect) == CHARDET_RESULT_OK)

chardet_get_charset(chardect, out_encode, CHARDET_MAX_ENCODING_NAME);

}

if(chardect)

chardet_destroy(chardect);

returnout_encode;

}

//#include "chardetect.h"

//char out_encode[CHARDET_MAX_ENCODING_NAME]

char * EncodeUtil::GetLocalEncoding(const char* in_str, unsigned int str_len, char* out_encode){

chardet_t chardect=NULL;

if(chardet_create(&chardect)==CHARDET_RESULT_OK){

if(chardet_handle_data(chardect, in_str, (unsigned int)str_len) == CHARDET_RESULT_OK)

if(chardet_data_end(chardect) == CHARDET_RESULT_OK)

chardet_get_charset(chardect, out_encode, CHARDET_MAX_ENCODING_NAME);

}

if(chardect)

chardet_destroy(chardect);

return out_encode;

}

2.编码的转换

编码转换,当然要知道源编码和目的编码了,源编码可以使用1的方法获取,当然你必须相信他能检测出来大部分的编码。对于检测不出来的,你就根据应用来尝试几种编码吧。比如对于我的应用,当检测不到html源码的编码时,绝大部分情况下,UTF-8 尝试是正确的(使用浏览器进行先验的,嘿嘿)。 这里呢,有一个问题,就是Linux系统的iconv并不能完美的转码。特别是我发现很多被识别为UTF-8的竟然用iconv 转 GB 编码失败,于是乎,找到了iconv的升级版==>http://www.gnu.org/software/libiconv/ 。对,就是它!

下载、编译、安装、使用,嘿嘿,这个有文档,你慢慢看吧,哈哈。 下面是一个比较好用的使用示例,相信够用了。呵呵

#ifndef ICONV_CONST

# define ICONV_CONST const

#endif

intEncodeUtil::charsetConvert(constchar*from_charset,constchar*to_charset,constchar*src,constintsrclen,char* save,intsavelen) {

if(save==NULL||srclen == 0) {

return-1;

}

save[0] = 0;

if(strcmp(from_charset, to_charset) == 0) {

if(savelen<=srclen)

strncat(save, src, savelen);

else

strncat(save, src, srclen);

returnsavelen>srclen ? srclen : savelen;

}

//convert

iconv_t cd;

intstatus = 0;//result

char*outbuf = save;//iconv outptr begin

ICONV_CONSTchar* inptr = src;

char* outptr = outbuf;

size_tinsize = srclen;

size_toutsize = savelen;

cd = iconv_open(to_charset, from_charset);

if((iconv_t)(-1) == cd){

return-1;

}

iconv(cd, NULL, NULL, NULL, NULL);

while(insize > 0) {

size_tres = iconv(cd, (ICONV_CONSTchar**) &inptr, &insize, &outptr,&outsize);

if(outptr != outbuf) {

outbuf=outptr;

*outbuf=0;

}

if(res == (size_t) (-1)) {

if(errno == EILSEQ) {

intone = 1;

iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one);

status = -3;

}elseif(errno == EINVAL) {

if(srclen == 0) {

status = -4;

gotodone;

}else{

break;

}

}elseif(errno == E2BIG) {

status = -5;

gotodone;

}else{

status = -6;

gotodone;

}

}

}

status = strlen(save);// ===  outbuf - save ;

done:

iconv_close(cd);

returnstatus;

}

#ifndef ICONV_CONST

# define ICONV_CONST const

#endif

int EncodeUtil::charsetConvert(const char *from_charset,const char *to_charset, const char *src, const int srclen, char* save,int savelen) {

if(save==NULL||srclen == 0) {

return -1;

}

save[0] = 0;

if (strcmp(from_charset, to_charset) == 0) {

if(savelen<=srclen)

strncat(save, src, savelen);

else

strncat(save, src, srclen);

return savelen>srclen ? srclen : savelen;

}

//convert

iconv_t cd;

int status = 0; //result

char *outbuf = save;//iconv outptr begin

ICONV_CONST char* inptr = src;

char* outptr = outbuf;

size_t insize = srclen;

size_t outsize = savelen;

cd = iconv_open(to_charset, from_charset);

if((iconv_t)(-1) == cd){

return -1;

}

iconv(cd, NULL, NULL, NULL, NULL);

while (insize > 0) {

size_t res = iconv(cd, (ICONV_CONST char**) &inptr, &insize, &outptr,&outsize);

if (outptr != outbuf) {

outbuf=outptr;

*outbuf=0;

}

if (res == (size_t) (-1)) {

if (errno == EILSEQ) {

int one = 1;

iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one);

status = -3;

} else if (errno == EINVAL) {

if (srclen == 0) {

status = -4;

goto done;

} else {

break;

}

} else if (errno == E2BIG) {

status = -5;

goto done;

} else {

status = -6;

goto done;

}

}

}

status = strlen(save);// === outbuf - save ;

done:

iconv_close(cd);

return status;

}

需要唠叨一句,不知道为什么,为什么这么底层的接口竟然 src 不用const 修饰,所以我传进来的const char *src 实际在函数中是有警告的,无奈,忽略吧。

3.OK ,结束了。哈哈。贴上一个多余的玩意儿,就是我的系统实际访问的接口。

intEncodeUtil::ConvertToGb(constchar* in_str,intstr_len,char* out_str,intout_str_len){

charencode[CHARDET_MAX_ENCODING_NAME];

encode[0]=0;

GetLocalEncoding(in_str,str_len,encode);

if(encode[0]==0){

//I'll try UTF-8 ,If you think it dosn't matter about undetect encode ,return -1 is ok

sprintf(encode,"%s","UTF-8");

//return -1;

}

returncharsetConvert(encode,"GB18030",in_str,str_len,out_str,out_str_len);

}

int EncodeUtil::ConvertToGb(const char* in_str, int str_len,char* out_str, int out_str_len){

char encode[CHARDET_MAX_ENCODING_NAME];

encode[0]=0;

GetLocalEncoding(in_str,str_len,encode);

if(encode[0]==0){

//I'll try UTF-8 ,If you think it dosn't matter about undetect encode ,return -1 is ok

sprintf(encode,"%s","UTF-8");

//return -1;

}

return charsetConvert(encode,"GB18030",in_str,str_len,out_str,out_str_len);

}

linux字符串编码转换函数,Linux C++ 字符串 编码识别、编码转换相关推荐

  1. linux内核的延时函数,linux中内核延时函数 (转)

    第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsi ...

  2. linux c 文件拷贝函数,Linux C函数库参考手册

    来自一本绝版的书,虽然没有函数 描述,但是最起码可以知道分类,就可以去 man 了 Linux C函数库参考手册 第1章字符测试 函数 isalnum(测试字符是否为英文字母或数字) isalpha( ...

  3. python字符串中find函数_Python之字符串常用花哨玩法

    字符串类型 在python中,字符串类型确实是一种很强大的类型,其中的功能函数更是令人震惊,这多么类都是谁写的,太感谢他了\(^o^)/ 当然,在实际工作中可能用不到那么多的函数,根据需求来嘛,一下介 ...

  4. linux时间与日期函数,Linux时间日期函数

    最近跑实验的时候需要获取函数的执行时间,因此变在网上搜集整理了,在Linux下跟时间有关的函数,保存在此,以备不时之需- asctime(将时间和日期以字符串格式表示) 相关函数 time,ctime ...

  5. linux协议栈skb操作函数,linux协议栈skb操作函数

    1,struct sk_buff数据结构 struct sk_buff{ //这两个结构必须放在最前面 struct sk_buff *next; struct sk_buff *prev; stru ...

  6. linux 内核 fget,fgets函数 linux中fgets函数怎么用

    一个函数该如何使用?我们最先要了解的就是这个函数的语法以及具体的含义是什么,所以今天我们就来看一看fgets函数在实际的运用过程当中是如何使用的,希望能给大家带来一定的帮助. fgets函数--lin ...

  7. python测试字符串类型的函数_python-02 数据类型 字符串str

    字符串str 一.字符串定义 概念:字符串是有序的 不可修改的,元素以引号包围的序列 引号类型:''单引号 ""双引号 " ""三引号 '''三单引号 ...

  8. php 中的字符串转数组函数,php中字符串转数组的函数是什么

    php中将字符串转换为数组的函数有:1.str_split()函数,语法"str_split(string,length)":2.explode()函数,可返回字符串数组:3.pr ...

  9. python编写函数、给定任意字符串_编写函数,给定任意字符串,找出其中只出现一次的字符,如果有多个这样的字符,就全部找出。...

    [简答题]编写程序,实现分段函数计算,如下表所示. x y x<0 0 0<=x<5 x 5<=x<10 3x-5 10<=x<20 0.5x-2 20< ...

最新文章

  1. Objective-C 内存管理之ARC规则
  2. Jupyter notebook 的使用
  3. 推荐系统笔记(简单概念)
  4. My1stServlet
  5. pytorch保存模型pth_Day159:模型的保存与加载
  6. HDU 3397 Sequence operation
  7. 集训2--进程控制理论
  8. CoreCLR文档翻译 - GC的设计
  9. 很大的.xls 文件导入sqlserver2005导入不全_python3 接口测试数据驱动之操作 excel 文件...
  10. go 判断元素是否在slice_golang 判断 两个slice 是否相等
  11. android组建之间通信_android组件间通信有哪些方式
  12. java 反射集合_Java反射的理解(六)-- 通过反射了解集合泛型的本质
  13. NYOJ题目325-zb的生日
  14. LoadRunner场景参数文件部分参数说明
  15. hdu 1421 搬寝室(dp)
  16. ug80浩强工具_ug浩强工具安装软件下载-ug浩强工具2.45 官方免费版-东坡下载
  17. Mybatis框架中Oracle使用BLOB字段存储图片并展示(详细步骤)
  18. iOS_数据库3_sqlite3基本操作
  19. B站 根据BV 获取av号 api
  20. Doris入门到精通-阶段一(简介安装使用)

热门文章

  1. FusionCharts简明教程(一)---建立FusionCharts图形
  2. 还原dede数据后系统基本参数空白无显示的解决方法
  3. JQuery学习笔记02-选择器把需要的东西揪出来(基础)
  4. 教你制作可以随身携带的FreeBSD系统[转]
  5. 居然出错.谁能帮我解决一下.
  6. IntelliJ IDEA(五) :酷炫插件系列
  7. 特征工程(二) :文本数据的展开、过滤和分块
  8. 详解tomcat的连接数与线程池
  9. ubuntu vim中文乱码问题
  10. 解决Windows Git Bash中文乱码问题