Chinaunix首页 | 论坛 | 博客
  • 博客访问: 200771
  • 博文数量: 489
  • 博客积分: 410
  • 博客等级: 下士
  • 技术积分: 2590
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-01 22:50
文章分类

全部博文(489)

文章存档

2011年(489)

我的朋友

分类:

2011-09-04 12:32:36

原文地址:怎么还犯低级错误? 作者:agu9899

想想自己写程序时间和数量也不少了吧,可是就在一个普通的上午,为了个小问题搞了两个小时,可能是老了,脑子很僵化吧,大家看看下面的一段代码:


/****************************************************************
 * $ID: iconv_test1.c 六, 31 10月 2009 20:12:22 +0800 gzq $ *
 * *
 * Description: *
 * *
 - Maintainer: (Bruce Gu) *
 * *
 * This file is free software; *
 * you are free to modify and/or redistribute it      *
 * under the terms of the GNU General Public Licence (GPL). *
 * *
 * Last modified: 六, 31 10月 2009 20:15:45 +0800 by gzq #
 ****************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
#include <string.h>
#include <errno.h>

int main(int argc,char **argvs)
{
    if (argc >1)
    {
    char *str_in = argvs[1];
    int in_len = strlen(str_in);
    char *str_out;
    str_out = (char *)malloc(in_len);
//    printf("now str_out add:%p\n",str_out);

    int out_len = in_len * 3;
    iconv_t cd = iconv_open("GBK","UTF-8");
    if (cd == (iconv_t) -1)
    {
     printf("error happend in:%s,line is:%d \r \nerror message:%s\n",__FUNCTION__,__LINE__,strerror(errno));    
     return -1;
    }

    int ret = iconv(cd,&str_in,&in_len,&str_out,&out_len);
//    printf("now str_out add:%p\n",str_out);


    if (ret <0)
     printf("error happend in:%s,line is:%d \r \nerror message:%s\n",__FUNCTION__,__LINE__,strerror(errno));    

    iconv_close(cd);

    if ((iconv_t) ret != (iconv_t) -1 || !in_len)
     printf("now utf-8 string is:%s\n",str_out);
        
    }
    else
    {
    printf("input need convert string \n.");
    }
}

/****************** End Of File: iconv_test1.c ******************/


程序的功能不言而喻了,但是如果你不编译执行此段代码,不知大家是否会看出此中的严重的错误。编译此文件后:gcc iconv_test1.c -g -o iconv_test1

执行
./iconv_test1 ah中国
打印结果如下:
now str_out add:0x892f008
now str_out add:0x892f00e
now utf-8 string is:
看到了吗?并没有报任何错误,但是结果就是不对。后来看看iconv的函数介绍,再添加了上两句打印str_out 的地址才发现了自己所犯下的严重错误。发现同样的指针变量str_out前后两次地址变了,iconv的定义如下:

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

首先out_buf是个指针的指针,执行iconv后,源码中的str_out已经指向了转换为utf-8字符串的尾端了。此时还天真认为str_out没有改变。认为str_out 就是转换后的utf-8字符串的首地址。

修改代码如下:

/****************************************************************
 * $ID: iconv_test.c 六, 31 10月 2009 16:10:35 +0800 gzq $ *
 * *
 * Description: *
 * *
 - Maintainer: (Bruce Gu) *
 * *
 * *
 * This file is free software; *
 * you are free to modify and/or redistribute it      *
 * under the terms of the GNU General Public Licence (GPL). *
 * *
 * Last modified: 六, 31 10月 2009 20:35:37 +0800 by gzq #
 ****************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
#include <string.h>
#include <errno.h>

int main(int argc,char **argvs)
{
    if (argc >1)
    {
    char *str_in = argvs[1];
    int in_len = strlen(str_in);
    char *str_out,*p_out;
    p_out = str_out = (char *)malloc(in_len);
    printf("now str_out add:%p\n",str_out);
    int out_len = in_len * 3;
    iconv_t cd = iconv_open("GBK","UTF-8");
    if (cd == (iconv_t) -1)
    {
     printf("error happend in:%s,line is:%d \r \nerror message:%s\n",__FUNCTION__,__LINE__,strerror(errno));    
     free(p_out);
     return -1;
    }

    int ret = iconv(cd,&str_in,&in_len,&str_out,&out_len);
    printf("now str_out add:%p\n",p_out);

    if (ret <0)
     printf("error happend in:%s,line is:%d \r \nerror message:%s\n",__FUNCTION__,__LINE__,strerror(errno));    

    iconv_close(cd);

    if ((iconv_t) ret != (iconv_t) -1 || !in_len)
     printf("now utf-8 string is:%s\n",p_out);
//     printf("now utf-8 string is:%s\n",str_out);

    free(p_out);
        
    }
    else
    {
    printf("input need convert string \n.");
    }
}

/****************** End Of File: iconv_test.c ******************/


执行
./iconv_test1 ah中国
打印结果如下:
now str_out add:0x9b06008
now str_out add:0x9b06008
now utf-8 string is:ah
阅读(117) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~