本例介绍了国标GB2312编码的基本原理。
GB2312编码又称为“汉字区位码”, 它按照汉字的汉语拼音顺序, 将汉字分区, 在每区定义固定的汉字数。
GB2312是我国国家标准汉字编码的一部分, 也是常用汉子编码GBK编码的一部分, 是非常常用的汉字编码。
GB2312使用两个字节表示一个汉字(即一个short int类型), 每个字节值大于0xA0并以此来判断某个字节究竟是汉字GB2312编码的一部分或是ASCII编码。
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
// 区位码将汉字分为87个区
#define TABLE_COUNT 87
// 区位码中每区共94个字符
#define TABLE_SIZE 94
// 定义表示一个GB2312汉字的联合体
typedef union {
short sChar; // 表示汉子编码, 16位
struct {
char cLow; // 汉字编码的高位
char cHigh; // 汉子编码的低位
};
} CHARSET, *LPCHARSET;
/**
* 将一个 4位长度的short int类型的数字转为字符串表示(16进制)
* 参数:pc, 一个指向CHARSET联合体的变量的指针
* 返回值:指向转化结果字符串的指针
*/
const char* ShortToString(const LPCHARSET pc) {
const int NUM = 16;
static char pBuffer[5] = "";
int i, nEach;
int nValue = (unsigned short)pc->sChar; // 将short int去掉符号转为整型
// 从数字的最低位开始, 诸位转化为字符(共 4 位)
for (i = 3; i >= 0; --i) {
if (nValue > 0) {
nEach = nValue % NUM;
nValue /= NUM;
if (nEach < 10) {
pBuffer[i] = '0' + nEach;
} else {
pBuffer[i] = 'A' + (nEach - 10);
}
} else {
pBuffer[i] = '0';
}
}
return pBuffer;
}
/**
* 将一个CHARSET结构体变量转化为一个GB2312编码汉字
* 参数:pc, 一个指向CHARSET联合体的变量的指针
* 返回值:一个指向表示汉字的字符串的指针
*/
const char* StructToString(const LPCHARSET pc) {
static char pBuffer[3] = "";
pBuffer[0] = pc->cHigh;
pBuffer[1] = pc->cLow;
return pBuffer;
}
int main(int argc, char* argv[]) {
// 定义汉字区位表结构体
CHARSET c;
int i, j;
c.sChar = 0;
// 显示封面
printf("/n/n/n/n/n/n/n");
printf("========================="
"========================="
"========================="
"=====/n");
printf("/t/t/t/t汉字区位表(基于GB2312)/n/n/n/n");
printf("/t/t/t/t 作者:Purple/n/n");
printf("========================="
"========================="
"========================="
"=====");
printf("/n/n/n/n/n请按回车键继续...");
getchar();
// 显示区位表
for (i = 1; i <= TABLE_COUNT; ++i) {
printf("=================================== ");
printf("第 %d 区", i);
printf(" ====================================");
c.cHigh =0xA0+ i;
printf(" ");
// 显示列号
for (j = 1; j <= 5; ++j) {
printf(" %d ", j);
}
for (j = 0; j < TABLE_SIZE; ++j) {
c.cLow =0xA0+ j + 1;
if (j % 5 == 0) {
// 显示行号汉字及编码
printf("/n%2d: %s[%s] ", j / 5 + 1, StructToString(&c), ShortToString(&c));
} else {
// 显示汉字及编码
printf("%s[%s] ", StructToString(&c), ShortToString(&c));
}
}
printf("/n/n/n请按回车键继续...");
getchar();
}
return 0;
}