免费注册 查看新帖 |

Chinaunix

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

一个关于iconv函数utf16转utf8码的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-07 17:55 |只看该作者 |倒序浏览
各位老大,我是新手,想请教各位,比如一个字串 "aaa\u6d4b", 我是先通过去除"\u"这个符号,然后再取得6d,4b转成utf-16编码,最后想通过iconv函数把6d4b在转成utf8编码(其他字符比如aaa不去动),可是iconv输出总是为空,不知道啥原因,望各位老大慷慨相助,以下是源码,写的不好,呵呵
void decode_jsstring(char *buf, char *OutStr){
        char *p, *q, *temp, *str;
        char buf_in[3];
        char buf_out[20];
        unsigned char c;
        iconv_t cd;
        char* pout = buf_out;
        ssize_t inlen;
        ssize_t outlen = 20;
        ssize_t n;

        bzero(buf_in, sizeof(buf_in));
        bzero(buf_out, sizeof(buf_out));
        for(p=buf, q=OutStr ;  *p ; p++, q++)
        {
                if(*p == '\\')
                        switch(*(p+1)){
                                case 'u':
                                        temp=q;
                                        buf_in[0]=*(p+4);
                                        buf_in[1]=*(p+5);
                                        sscanf(buf_in, "%x", &c);
                                        *q = c;
                                        q++;
                                        buf_in[0]=*(p+2);
                                        buf_in[1]=*(p+3);
                                        sscanf(buf_in, "%x", &c);
                                        *q = c;
                                        p+=5;
                                        str=strndup(temp, q+1-temp);
                                        *(str+2)='\0';
                                        inlen=q+1-temp;
                                        printf("str ,len :%s, %d\n", str,inlen);

                                        if((cd = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)-1) return NULL;
                                        iconv(cd, &str, &inlen, &pout, &outlen);

                                        printf("Output: %s,n= %d,inlen=%d,outlen=%d\n", pout,n,inlen,outlen);
                                        iconv_close(cd);
                                        //free(str);
                                        break;
                                case '\0':
                                        iconv_close(cd);
                                        break;
                                default:
                                        *q = *p;
                        }
                else
                        *q = *p;
        }
        *q='\0';
        //printf("%s\n",OutStr);
}

论坛徽章:
0
2 [报告]
发表于 2009-01-07 17:59 |只看该作者
在线等...

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
3 [报告]
发表于 2009-01-09 01:25 |只看该作者
我这里能得到结果:
aaa测

论坛徽章:
0
4 [报告]
发表于 2009-01-09 10:36 |只看该作者
原帖由 ynchnluiti 于 2009-1-9 01:25 发表
我这里能得到结果:
aaa测



奇怪了,我的printf("Output: %s,n= %d,inlen=%d,outlen=%d\n", pout,n,inlen,outlen);这边 pout总是空的,我源码如下,请您看下:

#include <stdio.h>
#include<sys/stat.h>
#include<unistd.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
#include <error.h>

#define BUFFLEN 2048

/* TODO: must implement real string decoder for lineXXX */
void decode_jsstring(char *buf, char *OutStr){
        char *p, *q, *temp, *str;
        char buf_in[3];
        char buf_out[20];
        unsigned char c;
        iconv_t cd;
        char* pin;
        char* pout = buf_out;
        ssize_t inlen;
        ssize_t outlen = 20;
        ssize_t n;

        bzero(buf_in, sizeof(buf_in));
        bzero(buf_out, sizeof(buf_out));
        for(p=buf, q=OutStr ;  *p ; p++, q++)
        {
                if(*p == '\\')
                        switch(*(p+1)){
                                case 'u':
                                        temp=q;
                                        buf_in[0]=*(p+4);
                                        buf_in[1]=*(p+5);
                                        sscanf(buf_in, "%x", &c);
                                        *q = c;
                                        q++;
                                        buf_in[0]=*(p+2);
                                        buf_in[1]=*(p+3);
                                        sscanf(buf_in, "%x", &c);
                                        *q = c;
                                        p+=5;
                                        str=strndup(temp, q+1-temp);
                                        *(str+2)='\0';
                                        inlen=q+1-temp;
                                        printf("str ,len :%s, %d\n", str,inlen);

                                        if((cd = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)-1) return NULL;
                                        iconv(cd, &str, &inlen, &pout, &outlen);
                                       
                                        printf("Output: %s,n= %d,inlen=%d,outlen=%d\n", pout,n,inlen,outlen);
                                        iconv_close(cd);
                                        //free(str);
                                        break;
                                case '\0':
                                        iconv_close(cd);
                                        break;
                                default:
                                        *q = *p;
                        }
                else
                        *q = *p;
        }
        *q='\0';
        //printf("%s\n",OutStr);
}

int load_file(char *filename, char *buf, int maxlen){
        int count;
        FILE *fp=fopen(filename, "r");
        if(fp==NULL){
                printf("cannot open file: [%s]\n", filename);
                return -1;
        }
        for(count=0;count<maxlen;count++){
                if(fread(&buf[count], 1, 1, fp)<=0) break;
        }
        fclose(fp);
        return count;
}

int main( int argc, char *argv[]){

        int getlen;
        char *filename=argv[1];
        struct stat statbuf;
        int MAX_LOAD_SIZE=0;

        if((stat(filename,&statbuf)) == -1){
                printf("open file failed");
                return -1;
        }
        MAX_LOAD_SIZE=statbuf.st_size;

        char buf[MAX_LOAD_SIZE+1];

        //load content
        getlen=load_file(filename, buf, MAX_LOAD_SIZE);
        if(getlen<=0) exit(1);
        buf[getlen]='\0';

        //printf("buf: %s\n",buf);
        unsigned char *OutStr = (unsigned char *) malloc (getlen * 2);
        decode_jsstring(buf, OutStr);
        //printf("%s\n",OutStr);
        free(OutStr);
        return 0;
}

论坛徽章:
0
5 [报告]
发表于 2009-01-09 10:38 |只看该作者
下面是编译和输出的结果,用的是RH9

[root@localhost tmp]# cat 3.text
aaa\u6d4b
[root@localhost tmp]# gcc -o 3 3.c
3.c: In function `decode_jsstring':
3.c:42: warning: assignment makes pointer from integer without a cast
3.c:47: warning: `return' with a value, in function returning void
[root@localhost tmp]# ./3 3.text
str ,len :Km, 2
Output: ,n= 1073790467,inlen=0,outlen=17

论坛徽章:
0
6 [报告]
发表于 2009-01-09 10:44 |只看该作者
希望各位大哥能附上源码,小弟感激啊,在线等...

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
7 [报告]
发表于 2009-01-09 20:16 |只看该作者
原帖由 gejiajie_01 于 2009-1-9 10:44 发表
希望各位大哥能附上源码,小弟感激啊,在线等...

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <string.h>
  4. #include <strings.h>
  5. #include <iconv.h>

  6. void decode_jsstring(char *buf, char *OutStr){
  7.     char *p, *q, *temp, *str;
  8.     char buf_in[3];
  9.     char buf_out[20];
  10.     unsigned int c;// unsigned char c;
  11.     iconv_t cd;
  12.     char* pout = buf_out;
  13.     ssize_t inlen;
  14.     ssize_t outlen = 20;
  15.     ssize_t n;

  16.     bzero(buf_in, sizeof(buf_in));
  17.     bzero(buf_out, sizeof(buf_out));
  18.     for(p=buf, q=OutStr ;  *p ; p++, q++)
  19.     {
  20.         if(*p == '\\')
  21.             switch(*(p+1)){
  22.                 case 'u':
  23.                     temp=q;
  24.                     buf_in[0]=*(p+4);
  25.                     buf_in[1]=*(p+5);
  26.                     sscanf(buf_in, "%x", &c);
  27.                     *q = c;
  28.                     q++;
  29.                     buf_in[0]=*(p+2);
  30.                     buf_in[1]=*(p+3);
  31.                     sscanf(buf_in, "%x", &c);
  32.                     *q = c;
  33.                     p+=5;
  34.                     str=(char *)strndup(temp, q+1-temp);
  35.                     *(str+2)='\0';
  36.                     inlen=q+1-temp;
  37.                     printf("str ,len :%s, %d\n", str,inlen);

  38.                     if((cd = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)-1) return;
  39.                     iconv(cd, &str, (size_t *)&inlen, &pout, (size_t *)&outlen);

  40.                     printf("Output: %s,n= %d,inlen=%d,outlen=%d\n", pout,n,inlen,outlen);
  41.                     iconv_close(cd);
  42.                     break;
  43.                 case '\0':
  44.                     iconv_close(cd);
  45.                     break;
  46.                 default:
  47.                     *q = *p;
  48.             }
  49.         else
  50.             *q = *p;
  51.     }
  52.     *q='\0';
  53. }

  54. int main( int argc, char *argv[])
  55. {
  56.     char *str = "aaa\u6d4b";
  57.     char out[128] = {0};

  58.     decode_jsstring(str, out);
  59.     printf("%s\n",out);
  60.     return 0;
  61. }
复制代码

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
8 [报告]
发表于 2009-01-09 20:19 |只看该作者

回复 #7 ynchnluiti 的帖子

ssh终端用的utf-8, 看到了输出,不知道是否已正确转码。
locale
LANG=C
LANGUAGE=zh_CN:zh
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=

$gcc -Wall decode.c -std=c99
decode.c: In function 'decode_jsstring':
decode.c:36: warning: implicit declaration of function 'strndup'
$ ./a.out
aaa测

论坛徽章:
0
9 [报告]
发表于 2009-01-12 11:43 |只看该作者
原帖由 ynchnluiti 于 2009-1-9 20:19 发表
ssh终端用的utf-8, 看到了输出,不知道是否已正确转码。





是的,完全正确,我的是:
root@localhost tmp]# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
[root@localhost tmp]# ./4
str ,len :Km, 2
Output: ,n= 1073830792,inlen=0,outlen=17
aaaKm

[root@localhost tmp]# cat 4.c
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <strings.h>
#include <iconv.h>

void decode_jsstring(char *buf, char *OutStr){
    char *p, *q, *temp, *str;
    char buf_in[3];
    char buf_out[20];
    unsigned int c;// unsigned char c;
    iconv_t cd;
    char* pout = buf_out;
    ssize_t inlen;
    ssize_t outlen = 20;
    ssize_t n;

    bzero(buf_in, sizeof(buf_in));
    bzero(buf_out, sizeof(buf_out));
    for(p=buf, q=OutStr ;  *p ; p++, q++)
    {
        if(*p == '\\')
            switch(*(p+1)){
                case 'u':
                    temp=q;
                    buf_in[0]=*(p+4);
                    buf_in[1]=*(p+5);
                    sscanf(buf_in, "%x", &c);
                    *q = c;
                    q++;
                    buf_in[0]=*(p+2);
                    buf_in[1]=*(p+3);
                    sscanf(buf_in, "%x", &c);
                    *q = c;
                    p+=5;
                    str=(char *)strndup(temp, q+1-temp);
                    *(str+2)='\0';
                    inlen=q+1-temp;
                    printf("str ,len :%s, %d\n", str,inlen);

                    if((cd = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)-1) return;
                    iconv(cd, &str, (size_t *)&inlen, &pout, (size_t *)&outlen);

                    printf("Output: %s,n= %d,inlen=%d,outlen=%d\n", pout,n,inlen,outlen);
                    iconv_close(cd);
                    break;
                case '\0':
                    iconv_close(cd);
                    break;
                default:
                    *q = *p;
            }
        else
            *q = *p;
    }
    *q='\0';
}

int main( int argc, char *argv[])
{
    char *str = "aaa\\u6d4b";
    char out[128] = {0};

    decode_jsstring(str, out);
    printf("%s\n",out);
    return 0;
}

str应该是红色的字才是,而且你的为啥会没有 Output: ,n= 1073830792,inlen=0,outlen=17
输出呢?

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
10 [报告]
发表于 2009-01-12 13:40 |只看该作者

回复 #9 gejiajie_01 的帖子

是不是没转就直接输出了,
我再试一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP