linux gbk英文转unicode,GBK转unicode码查询表

大约大半年前完成一个矢量字库类,使用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。

完整代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97#include 

#include 

#include 

#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 

{

//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码函数如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24int 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 

{

if (gb_temp[i] <= 0x80)

{

unicode[j] = gb_temp[i];

i++;

}

else

{

unsigned short int temp;

temp = (gb_temp[i] <

unicode[j] = gbkuni30[temp];

i += 2;

}

}

return j;

}

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

测试函数如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16void 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 

{

printf("gbk: %02x %02x,unicode: %x\n", p[i], p[i+1], unicode[i]);

}

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值