免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 19472 | 回复: 11
打印 上一主题 下一主题

[C] 请问iconv函数到底怎么用? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-28 18:15 |只看该作者 |倒序浏览
以下代码实现从ACSII字符集到UCS-2LE字符集的转换,但在调用ICONV函数时崩溃了!!!

#include <stdio.h>
#include <locale.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>

int main(int argc, char * argv[])
{
&nbsp;&nbsp;&nbsp;&nbsp;int ret;
&nbsp;&nbsp;&nbsp;&nbsp;char str[10] = {0};
&nbsp;&nbsp;&nbsp;&nbsp;int src_len;
&nbsp;&nbsp;&nbsp;&nbsp;int dest_len;
&nbsp;&nbsp;&nbsp;&nbsp;char *dest;
&nbsp;&nbsp;&nbsp;&nbsp;iconv_t conv;

&nbsp;&nbsp;&nbsp;&nbsp;strcpy(str, "test");

&nbsp;&nbsp;&nbsp;&nbsp;src_len = strlen(str)+ 1;
&nbsp;&nbsp;&nbsp;&nbsp;dest_len = src_len * 2;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;dest = (char*)malloc(dest_len);
&nbsp;&nbsp;&nbsp;&nbsp;bzero(dest, dest_len);

&nbsp;&nbsp;&nbsp;&nbsp;conv = iconv_open("UCS-2LE", "ASCII");
&nbsp;&nbsp;&nbsp;&nbsp;if (conv == (iconv_t)-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("iconv_open: %d\n", errno);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;ret = iconv(conv, (char**)&str, &src_len, &dest, &dest_len);  <<=== 崩溃了?WHY?ICONV函数倒底应该怎么使用?
&nbsp;&nbsp;&nbsp;&nbsp;if (ret == -1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("iconv: %d\n", errno);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;//printf("%s - %S\n", str, dest);

&nbsp;&nbsp;&nbsp;&nbsp;iconv_close(conv);
&nbsp;&nbsp;&nbsp;&nbsp;free(dest);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}

谢谢!!

[ 本帖最后由 逸远 于 2008-6-28 18:17 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-06-28 18:53 |只看该作者
出错信息呢。。。

论坛徽章:
0
3 [报告]
发表于 2008-06-28 19:12 |只看该作者
段错误,直接崩了~

论坛徽章:
0
4 [报告]
发表于 2008-06-28 19:23 |只看该作者
原帖由 逸远 于 2008-6-28 19:12 发表
段错误,直接崩了~

你这样给的信息太少,不容易判断的。。最好把出错信息以及你自己对它出错的定位讲一下

论坛徽章:
0
5 [报告]
发表于 2008-06-28 19:27 |只看该作者
GDB调试时的错误信息:

Program received signal SIGSEGV, Segmentation fault.
oxb7e59fcd in ?? ()

直接在终端运行的错误信息:
Segmentation fault.

定位ICONV函数调用那行的原因是在GDB中调试时运行到那句就挂了,并打印出如上信息。

[ 本帖最后由 逸远 于 2008-6-28 19:28 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2008-06-28 20:34 |只看该作者
是否有中文?
PS:malloc后记得判断一下是否分配成功。

论坛徽章:
0
7 [报告]
发表于 2008-06-28 21:03 |只看该作者

回复 #6 77h2_eleven 的帖子

没有中文,所有的代码都在上面。

malloc是成功了的,并且bzero了的。

论坛徽章:
0
8 [报告]
发表于 2008-06-28 22:14 |只看该作者
经过测试,发现这样可以正常调用ICONV函数,不会崩溃。而且从函数返回的结果为0来看,函数调用成功了,但转换结果好像不对。

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

int main(int argc, char * argv[])
{
    int ret;
    //char str[10]={0};

    char *str = (char*)malloc(10); // 在堆上分配,这样调用ICONV函数则不会崩溃? WHY? 难道不能使用栈上的内存??

    int src_len;
    int dest_len;
    char *dest;
    iconv_t conv, conv2;

    strcpy(str, "test");

    src_len = strlen(str)+ 1;
    dest_len = src_len * 2;
   
    dest = (char*)malloc(dest_len);
    bzero(dest, dest_len);

    conv = iconv_open("UCS-2LE", "ASCII");
    if (conv == (iconv_t)-1) {
        printf("iconv_open: %d\n", errno);
        return -1;
    }
   
    ret = iconv(conv, (char**)&str, &src_len, &dest, &dest_len);
    if (ret == -1) {
        printf("iconv: %d\n", errno);
        return -1;
    }

    printf("%s - %S\n", str, dest);
    iconv_close(conv);
    free(dest);
    free(str);
   
    return 0;
}


哪位帮忙解释下? ICONV函数到底应该如何使用? 郁闷中.....

[ 本帖最后由 逸远 于 2008-6-28 22:18 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2008-06-29 04:07 |只看该作者
man 3 iconv
size_t iconv(iconv_t cd,
                     char **inbuf, size_t *inbytesleft,
                     char **outbuf, size_t *outbytesleft);
...
       The iconv function converts one multibyte character at a time, and  for
       each   character   conversion   it  increments  *inbuf  and  decrements
       *inbytesleft by the number of  converted  input  bytes,  it  increments
       *outbuf  and decrements *outbytesleft by the number of converted output
       bytes, and it updates the conversion state contained in cd.   The  con-
       version can stop for four reasons:
....

*inbuf会被更新, 因此你的代码出现段错误,你应该这么调:
char *s = src;
char *d = dest;
iconv(conv, (char**)&s, &src_len, &d, &dest_len);

8楼的代码不对是iconv参数类型不对,src_len及dest_len应该是size_t而不是int, 请不要忽略编译警告。
另外 src_len应该是 strlen(str), 不包含'\0'

[ 本帖最后由 carleo21 于 2008-6-29 04:37 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2008-06-29 08:11 |只看该作者
原帖由 carleo21 于 2008-6-29 04:07 发表
man 3 iconv
size_t iconv(iconv_t cd,
                     char **inbuf, size_t *inbytesleft,
                     char **outbuf, size_t *outbytesleft);
...
       The iconv function converts ...


确实,搞定了,受教了。谢谢~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP