LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2768|回复: 7

LINUX iconv编码转换问题 求教,谢谢。

[复制链接]
发表于 2006-10-23 11:19:05 | 显示全部楼层 |阅读模式
最近小弟要做一个类似于网页信息抓取的东西,该网站采用gbk编码,由于我抓取该网站html页面中的内容后,要将它做为某种文件的文件名保存,因为系统为utf-8编码,所以需要从gbk转至utf-8,但我使用iconv函数库进行转换,却屡次不能成功,所以想请朋友们帮忙看一下这段短代码.
  小弟代码写的不是太好,请见谅。
  谢谢!
  1. /*function convert gbk to linux supported utf-8*/
  2. /*char *name是一个存有gbk编码的中文数据,以\0结尾*/
  3. int TC_convert_gbk_to_utf8(char *name)
  4. {
  5.        /*定义两个缓冲区*/
  6.         char buffer1[MAX_VIDEO_NAME_LENGTH];
  7.         char buffer2[MAX_VIDEO_NAME_LENGTH];
  8.         iconv_t cd;
  9.         size_t in_len;
  10.         size_t out_len = MAX_VIDEO_NAME_LENGTH - 1;
  11.        /*作一些初始化*/
  12.         memset(buffer1, '\0', sizeof(buffer1));
  13.         memset(buffer2, '\0', sizeof(buffer2));
  14.         /*get the max length to be converted*/
  15.         in_len = strlen(name) + 1;
  16.        
  17.         /*copy the oringinal code to the temp buffer*/
  18.         strcpy(buffer1, name);
  19.         /*clear the orginale buffer*/
  20.         memset(name, '\0', sizeof(name));
  21.        
  22.         /*create a convert descriptor*/
  23.         cd = iconv_open("UTF-8", "GBK");
  24.         if(cd == (iconv_t)-1)
  25.         {
  26.                 printf("cannot get a convert descriptor!\n");
  27.                 return -1;
  28.         }
  29.        
  30.        //下边一行代码总是出现段错误,但是name确实数据合法。
  31.         if(iconv(cd, &buffer1, &in_len, &buffer2, &out_len) == 0)
  32.         {
  33.                 /*copy back the converted character*/
  34.                /*将内容写至name中带回*/
  35.                strcpy(name, buffer2);
  36.                 /*close the descriptor*/
  37.                 iconv_close(cd);       
  38.                 return 0;
  39.         }       
  40.         /*close the descriptor*/
  41.         iconv_close(cd);
  42.         return -1;       
  43. }
复制代码
发表于 2006-10-23 11:44:05 | 显示全部楼层
这是我一个在用的函数,看起来似乎和你的差不多嘛
  1. int my_iconv(char *charset_to, char *charset_from, char *buff_out, u_int32_t len_out, char *buff_in, u_int32_t len_in)
  2. {
  3.   int n = len_out;
  4.   iconv_t convd;

  5.   convd = iconv_open (charset_to, charset_from);
  6.   if (convd == (iconv_t)(-1))
  7.   {
  8.     return 0;
  9.   }
  10.   iconv (convd, &buff_in, &len_in, &buff_out, &len_out);
  11.   iconv_close(convd);
  12.   return n - len_out;
  13. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-10-23 11:46:21 | 显示全部楼层
哦,你是写回传进来的name的空间阿,那是不够的,utf8编码后长度比gbk的要长
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-23 11:58:32 | 显示全部楼层
#define MAX_VIDEO_NAME_LENGTH 512
但是实际上我考虑过这个问题,我发现传过来的name长度一般只有17个左右的字节,直观上看不会出错吧,然而却总是提示段错误,让我相当不明白。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-23 12:02:33 | 显示全部楼层
还有想问兄弟一句,比如
”我出生于   1322“
这样的GBK编码,如果直接进行UTF-8转换,里边的空格以及1322也会一同转换吗?
谢谢。
回复 支持 反对

使用道具 举报

发表于 2006-10-23 13:39:41 | 显示全部楼层
应该也一起转的
回复 支持 反对

使用道具 举报

发表于 2006-10-23 14:03:00 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-23 22:01:09 | 显示全部楼层
现在才发现,原来错误出在那个buffer的声明上:
char buffer[12[;
buffer的类型是char *const;
对buffer取地址,则得到const char**类型,iconv会让这些指针数值变化,因此出现了内存访问错误,也即段错误。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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