大约大半年前完成一个矢量字库类,使用freetype库从矢量字库中读取字符轮廓,然后转成只有0、1的缓冲区,可以使用许多场合。涉及了freetype的操作,同时还有字符编码方面的知识。前不久,有同事反映说我提供的东西不能生成“绿”字。经测试,的确如此。查找代码发现原来编码转换表不全面,没有“绿”字的unicode码。那个对应表是在网上找的,自己也没做全面测试——我不会无聊到所有的汉字都测试一遍。

后来仔细一想,觉得有必要自己生成一个自己看得懂的查询表,并且比较全面的。于是找啊找,不小心找到了一个专门介绍编码的网站,找到了一个号称是GB18030和unicode对应的文本文件。具体地址是:http://icu-project.org/repos/icu/data/trunk/charset/source/gb18030/gbkuni30.txt。这个网站还有其它许多有用的资料,虽然是英文的,但认真看看,十分有用。至于如何查找,有志之士应该十分清楚,就不在此献丑了(写到这里,突然想到,在许多工作时间中,许多东西都有手把手教——甚至一些简单的东西,看来这种做法要改改了])。

为了在程序中使用那个表,于是自己写了生成查询表的小程序。程序很简单,就是直接用上述地址的文件生成一个一维数组。网上有类似的表,有的数组是二维的,查找不方便。下面的程序生成的是数组是按照GBK编码排序的,就是说,直接用GBK的编码查找数组即得到unicode码。比如,汉字“绿”的GBK编码是0xc2cc,则数组的第0xc2cc偏移的值就是“绿”的unicode编码:0x7eff。

完整代码如下:

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

#define ARRAY "gbkuni30"
#define MAX_LEN 65535   // 2字节最大数
static unsigned short big_buffer[MAX_LEN] = {0};

// 源文件
#define SRC "gbkuni30.txt"

// 生产的头文件
#define DST "gbkuni30_gen.h"

int make_charmap_gb18030()
{
    char buffer[16] = {0};
    char* p = NULL;
    FILE* fp_c = NULL;
    FILE* fp = NULL;
    int len = 0;
    int x1 = 0;
    int x2 = 0;
    int i = 0;
    int max_num = 0;
    int cnt = 0;

fp = fopen(SRC, "r");
    if (fp == NULL)
    {
        printf("open fileerror!!\n");
        return -1;
    }

fseek(fp, 0, SEEK_END);
    len = ftell(fp);
    fseek(fp,0,SEEK_SET);

printf("file len: %d\n", len);

fp_c = fopen(DST, "w+");
    if (fp_c == NULL)
    {
        printf("open fileerror!!\n");
        return -1;
    }

fprintf(fp_c, "/**********************************************************************************/\n");
    fprintf(fp_c, "/*            GBK(GB18030) to UNICODE table, powered by LateLee                */\n");
    fprintf(fp_c, "/*                       http://www.latelee.org                                 */\n");
    fprintf(fp_c, "/*                        %s%s                                  */\n", __DATE__, __TIME__);
    fprintf(fp_c, "/* The source file comesfrom:                                                   */\n");
    fprintf(fp_c, "/*http://icu-project.org/repos/icu/data/trunk/charset/source/gb18030/gbkuni30.txt*/\n");
    
    fprintf(fp_c, "/**********************************************************************************/\n");

fprintf(fp_c, "#ifndef__GBK2UNICODE__H\n");
    fprintf(fp_c, "#define __GBK2UNICODE__H\n\n");

fprintf(fp_c, "");
    fprintf(fp_c, "static unsigned short %s[] =\n{\n", ARRAY);

while (fgets(buffer, 32, fp) != NULL)
    {
        sscanf(buffer, "%x:%x\n", &x1, &x2);
        
        //printf("%s",buffer);
        //printf("%04x %x\n",x1, x2);
        //fprintf(fp_c, "0x%04x,0x%x,\n", x1, x2);
        big_buffer[x2] = x1;
        if (x2 > max_num)
            max_num = x2;

}

printf("max num: %d%x\n", max_num, max_num);
    for (i = 0; i < max_num + 1; i++)
    {
        //printf("0x%04x\n",big_buffer[i]);
        fprintf(fp_c, "0x%04x,", big_buffer[i]);
        cnt++;
        if (cnt % 10 == 0)
        {
            fprintf(fp_c, "   // line num %d \n", cnt / 10 - 1);
        }
    }
    fprintf(fp_c, "\n");
    fprintf(fp_c, "};\n\n");
    fprintf(fp_c, "#endif//__GBK2UNICODE__H\n");
    fprintf(stdout, "Job done!\n");

fclose(fp);
    fclose(fp_c);

return 0;

}

GBK转换成unicode码函数如下:

int gbk_to_unicode(unsigned short int* unicode, const char* gb, int len)
{
    int i,j;
    i = 0;
    unsigned char* gb_temp = (unsigned char *)gb;   //必须转换成无符号

for(j = 0; i < len; j++)
    {
        if (gb_temp[i] <= 0x80)
        {
            unicode[j] = gb_temp[i];
            i++;
        }
        else
        {
            unsigned short int temp;
            temp = (gb_temp[i] << 8) + gb_temp[i+1];
            unicode[j] = gbkuni30[temp];
            i += 2;
        }
    }

return j;
}

注意上面的函数的寻址方式,这里会涉及到大小端的问题,寻址方式一定要和生成的查询表对应。这里转换得到的temp的值就是汉字的GBK码,直接查找数组即得到unicode码。

测试函数如下:

void main()
{
    make_charmap_gb18030();
    printf("total len:%d(%.1fKB)\n", sizeof(gbkuni30), sizeof(gbkuni30) / 1024.0);

const char* p="啊";
    int len = (int)strlen(p);
    unsigned short* unicode = new unsigned short[len];
    int unicode_len = 0;

unicode_len = gbk_to_unicode(unicode, p, len);
    for (int i = 0; i < unicode_len; i++)
    {
        printf("gbk: %02x %02x,unicode: %x\n", p[i], p[i+1], unicode[i]);
    }
}

参考资料:

Unicode、GB2312、GBK和GB18030中的汉字:http://www.fmddlmyy.cn/text24.html

GB18030编码研究以及GBK、GB18030与Unicode的映射:http://www.fmddlmyy.cn/text30.html

浅谈文字编码和Unicode(上):http://www.fmddlmyy.cn/text16.html

浅谈文字编码和Unicode(下)::http://www.fmddlmyy.cn/text17.html

迟,写于2013年8月18日睡前

GBK转unicode码查询表相关推荐

  1. 使用python实现GBK转unicode码查询表

    接触python有一段时间了,但没有专门学习基础知识,写代码时总是到网上找资料.不过,相信经过练习可以慢慢积累.本文拿以前写的小程序练手.参见文章<GBK转unicode码查询表的改进>. ...

  2. GBK转unicode码查询表的改进

    上篇文章<GBK转unicode码查询表>中有一个美中不足的地方,就是占用的内存空间稍大了一点,约128KB,当然,对于PC这种平台无所谓,但对于一些场合来说,能省内存就省内存,何况那个表 ...

  3. 汉字编码(【Unicode】 【UTF-8】 【Unicode与UTF-8之间的转换】 【汉字 Unicode 编码范围】【中文标点Unicode码】【GBK编码】【批量获取汉字UNICODE码】)

    参考博客: Unicode与UTF-8互转(C语言实现):http://blog.csdn.net/tge7618291/article/details/7599902 汉字 Unicode 编码范围 ...

  4. [编码]ASCII、GBK、Unicode(万国码) 和 UTF-8

    American ASCII编码 (American Standard Code for Information Interchange,美国信息互换标准代码)  China    gbk编码     ...

  5. ASCII、GB2312、GBK、Unicode、UTF-8介绍和转换

    1.ASCII码 上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定.这被称为 ASCII 码,一直沿用至今.ASCII 码一共规定了128个字符的编码,比如空格S ...

  6. Visual Studio——多字节编码与Unicode码

    多字节字符与宽字节字符 1) char与wchar_t 我们知道C++基本数据类型中表示字符的有两种:char.wchar_t.  char叫多字节字符,一个char占一个字节,之所以叫多字节字符是因 ...

  7. 字符集ASCII、GBK、UNICODE、UTF在储存字符时的区别

    ASCII编码(American Standard Code for Information Interchange,美国信息互换标准代码),使用127个8进制字节表示英文和半角字符. GBK (Gu ...

  8. java打印unicode_java程序实现Unicode码和中文互相转换

    有了前一篇文章的了解,大概了解了unicode编码格式了 ANSI:汉字区的内码范围高字节从B0-F7,低字节从A1-FE Unicode:汉字的Unicode编码范围为\u4E00-\u9FA5 \ ...

  9. java 输出13060个繁体字集的Unicode码

    BIG5是目前中国台湾和中国香港地区普遍使用的一种繁体汉字的编码标准,包括440个符号,一级汉字5401个,二级汉字7652个,共计13060个汉字,所谓一级汉字与二级汉字对应于常用汉字和不常用汉字. ...

最新文章

  1. Activity的启动模式与flag详解
  2. 迪普科技:G20峰会背后的网络安全守护者
  3. 深入解析Javascript中this关键字的使用
  4. 新手必知20点VC技巧【转】
  5. 云计算之IaaS 中间件
  6. android UI开源库
  7. fg、bg、jobs、、ctrl + z
  8. 理解Attention机制原理及模型
  9. 简单的签到代码_签到功能,用 MySQL 还是 Redis ?
  10. 圆钢孔型计算机模拟,第五章 金属塑性加工ppt课件.ppt
  11. 用python生成一段关于文字的二维码(关于刷网课的)
  12. 互联网晚报 | 8月22日 星期日 | 抖音回应腾讯《扫黑风暴》相关投诉;比亚迪半导体被中止上市审核;三星正式推出UPC技术...
  13. 生物计算机教学,信息技术与高中生物教学的整合
  14. conda安装requirement.txt指定的依赖包
  15. 飞秋FeiQ2013特色功能列表
  16. 疯狂ios讲义之疯狂打飞机(2)
  17. html创建一个四行三列表单,HTML(三)表格table与表单form的基本使用
  18. 基于OpenCV做“三维重建”(1)--找到并绘制棋盘
  19. 网页控制台控制视频倍速
  20. Nginx网站服务(安装nginx、平滑升级nginx、nginx各种访问配置)

热门文章

  1. 首发Android 13!谷歌Pixel 7 Pro渲染图曝光:后置相机模组吸睛
  2. 净利下降7成、新业务“扛大旗” 阿里转型更需耐心
  3. 国庆档首日票房破2亿 长津湖票房占比过半
  4. 国产性能车天花板?145万买极星1,认真的么?
  5. 他走了,留下了3800亿元的帝国
  6. 任正非之女姚安娜正式出道
  7. 国家广播电视总局:未实名制注册的用户不能打赏 未成年用户不能打赏
  8. 马斯克:特斯拉汽车产量今年有望达到50万辆
  9. 罗永浩直播带货被吐槽不是全网最低价 本人亲自回应了
  10. iPhone 12或支持全新短距离WiFi标准 数据传输更快