请教。关于汉字编码转换UTF-8->GB2312。

sanor
请教。关于汉字编码转换UTF-8->GB2312。

大家有做过这个的实现吗?UTF-8到GB2312的转换。
linux汉字编码为UTF-8,汉字库编码为GB2312。所以需要UTF-8到GB2312的转换。
交叉工具链中没有iconv函数,所以需要自己实现。网上搜到的全都是windows下的不可移植代码。
或者unicode到GB2312的转换。现在可以从UTF-8转到unicode。
多谢大家不吝赐教。

net_robber
man iconv

ruoyisiyu
[quote]原帖由 [i]net_robber[/i] 于 2008-6-11 13:28 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8570101&ptid=1156466][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
man iconv [/quote]
汗~~人家说了没有iconv了:mrgreen: :mrgreen:

jigloo
关键字:gb2312.txt
网上很多人作过这个
[url]http://download.csdn.net/source/205564[/url]

cugb_cat
把iconv的代码下载下来,抄一抄~~!

jigloo
iconv的代码比较复杂,不适合楼主的需要。(估计楼主是要在嵌入式上用)

net_robber
如5楼说的,摘出需要的部分用

源代码都给你了,自己复制一下不好么??

sanor
汗。iconv源码。。:em06:

cobras
UTF只是UNICODE的一种表现形式,
UTF-8是用字节序列来表示UNICODE
还有UTF-16和UTF-32等等形式
若要将UTF-8转换为GB2312,应该先将UTF-8转换为UNICODE(一般用UTF-16表示即可,当然用UTF-32表示就更完整了),然后通过查表来实现UNICODE到GB2312的转换.

sanor
多谢楼上指点。那请再问我如何通过查表得到unicode与gb2312间的映射关系?是否有公式或法则?
刚才看了unicode字符映射表,目前状况大致如:
汉字“啊”,通过utf-8转unicode得到其字符编码为0x554a,unicode字符映射表里0x554a的位置确实是“啊”字。但是不知道如何将之与gb2312的1601对应。“啊”在gb2312汉字库中的区位码是1601。
请指教。谢谢。

cobras
这个简单,写个Win32程序在Windows xp中运行

safedead
回复 #1 sanor 的帖子

cp /usr/share/i18n/charmaps/GB18030.gz ./
gzip -d GB18030.gz
得到文本文件GB18030
里面就是unicode和GB18030的对应关系
其它的依此类推

这个文件很容易看懂,编个程序读取后就得到转换表
利用unicode为桥梁,可以进行各种字符集转换

figofuture
iconv也没有什么复杂的,基本原理不正如楼上说言吗?!

jigloo
最烦楼上这样的,没看过代码就乱说。

nicozhou
等我找找,前两天我还在折腾这个。

nicozhou
应该差不多的吧,不知道够不够lz用。我们是先自己建好unicode2gb2312的映射表,然后查这张表(二分法)的。其它的只要调这个接口就可以了。

UTF8应该可以类似这样做吧。反正我这边似可以正常的显示中文的。

UINT16 Unicode_to_Gb2312(UINT16 unidata)
{
    UINT16                      first = 0;
    UINT16                      last = MAX_UNI2GB_LIST - 1;
    UINT16                      middle = 0;
    UINT16                      des_pos = MAX_UNI2GB_LIST + MAX_UNI2GB_LIST;
    UINT16                      gb_code;

    if(unidata < IG_FONT_ASCII_BEGIN)
    {
        return OSD_FAILURE;
    }
    else if(unidata <= IG_FONT_ASCII_END)
    {
        return unidata;
    }
    else if(unidata < 0x00A4 || unidata > 0xFFE5)
    {
        return OSD_FAILURE;
    }

    while(first <= last)
    {
        middle = (first + last) & 0xfffe;
        if(unicode2gb2312[middle] == unidata)
        {
            des_pos = middle;
            break;
        }
        else if(unicode2gb2312[middle] > unidata)
        {
            last = (middle>>1) - 1;
        }
        else if(unicode2gb2312[middle] < unidata)
        {
            first = (middle>>1) + 1;
        }
    }

    if(des_pos > (MAX_UNI2GB_LIST + MAX_UNI2GB_LIST) - 1)
    {
        return OSD_FAILURE;
    }
    else
    {
        des_pos ++;
        gb_code = unicode2gb2312[des_pos];
        return gb_code;
    }
}

[[i] 本帖最后由 nicozhou 于 2008-6-11 21:51 编辑 [/i]]

nicozhou
难道额理解错了?

wsswan
上 Google 搜索 gb2312.txt 就能找到对照表,根据里面的算法做就可以了。没啥技术含量。问题是你确定用的是 GB2312 字符集么?要知道 GB2312 连一些基本的标点符号都没有,例如 ·×

figofuture
[quote]原帖由 [i]jigloo[/i] 于 2008-6-11 21:16 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8573417&ptid=1156466][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
最烦楼上这样的,没看过代码就乱说。 [/quote]
看没看代码很重要吗?有了思路后面不就一个实现而已。去看iconv的源码只不过花费一些时间而已,未必不适合嵌入式系统,你也没有调查过捏。

不过我并不烦你,有容乃大,哈哈!

jigloo
真像你说的这样,那些自己做转换的人都成了傻子?还有容乃大,先看代码再来说话。