1 /*
2 * 参考: http://zh.wikipedia.org/wiki/GB_2312
3 * http://zh.wikipedia.org/wiki/EUC
4 * http://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F
5 * x86处理器为Little endian
6 * EUC全名为Extended Unix Code, 是一个使用8位编码来表示字符的方法.
7 * 它使用了一些兼容于ISO/IEC 2022区位码的94x94编码表, 把每个区位加上0xA0来表示, 以便兼容于ASCII.
8 * 它主要用于表示及储存汉语文字, 日语文字及朝鲜文字.
9 * EUC-CN是GB 2312最常用的表示方法. 浏览器编码表上的"GB2312", 通常都是指"EUC-CN"表示法.
10 * GB 2312中对所收汉字进行了"分区"处理, 每区含有94个汉字/符号. 这种表示方式也称为区位码.
11 * 01-09区为特殊符号
12 * 16-55区为一级汉字, 按拼音排序.
13 * 56-87区为二级汉字, 按部首/笔画排序.
14 * 10-15区及88-94区则未有编码.
15 * 在使用GB2312的程序通常采用EUC储存方法, 以便兼容于ASCII. 浏览器编码表上的"GB2312", 通常都是指"EUC-CN"表示法.
16 * 每个汉字及符号以两个字节来表示, 第一个字节称为"高位字节", 第二个字节称为"低位字节".
17 * "高位字节"使用了0xA1-0xF7(把01-87区的区号加上0xA0), "低位字节"使用了0xA1-0xFE(把01-94加上0xA0).
18 * "高位字节"表示区号每一个区记录94个汉字, "低位字节"表示位号为该字在该区中的位置.
19 * 由于一级汉字从16区起始, 汉字区的"高位字节"的范围是0xB0-0xF7, "低位字节"的范围是0xA1-0xFE, 占用的码位是72*94=6768.
20 * 其中有5个空位是D7FA-D7FE。
21 * 例如"啊"字在大多数程序中, 会以两个字节, 0xB0(第一个字节)0xA1(第二个字节)储存. (与区位码对比: 0xB0=0xA0+16, 0xA1=0xA0+1).
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 int main(int argc, char *argv[])
28 {
29 unsigned char hz[3];
30 unsigned char hzk[16][2];
31 int i,j;
32 FILE *fp;
33 if ((fp = fopen("HZK16", "r")) == NULL) {
34 printf("Can't open ASC12!\n");
35 } else {
36 printf("请输入一个汉字:");
37 scanf("%s", hz);
38 printf("0x%02x,0x%02x\n", hz[0], hz[1]);
39 /*
40 * 减0xa0是因为EUC表示法中对数据进行了加上0xa0的处理,
41 * 减1是因为数组是以0为开始而区号位号是以1为开始的,
42 * 乘32是因为16*16点阵每个汉字占用16*16bit=16*2byte空间.
43 */
44 fseek(fp, (94 * ((hz[0] - 0xa0) - 1) + ((hz[1] - 0xa0) - 1)) * 32, SEEK_SET);
45 fread(hzk,32,1,fp);
46 for (i = 0; i < 16; i++) {
47 for (j = 0; j < 2; j++) {
48 printf("0x%02x\t", hzk[i][j]);
49 }
50 for (j = 0; j < 2; j++) {
51 printf("%c%c%c%c%c%c%c%c", ((hzk[i][j] >> 7) & 0x01) + ' ',
52 ((hzk[i][j] >> 6) & 0x01) + ' ',
53 ((hzk[i][j] >> 5) & 0x01) + ' ',
54 ((hzk[i][j] >> 4) & 0x01) + ' ',
55 ((hzk[i][j] >> 3) & 0x01) + ' ',
56 ((hzk[i][j] >> 2) & 0x01) + ' ',
57 ((hzk[i][j] >> 1) & 0x01) + ' ',
58 ((hzk[i][j] >> 0) & 0x01) + ' ');
59 }
60 putchar('\n');
61 }
62 fclose(fp);
63 }
64 system("PAUSE");
65 return 0;
66 }