嵌入式系統 (如手機簡訊顯示) 常需處理漢字。流程:接收 UTF-16 編碼文字 → 查 Unicode 碼表找 GB2312 位置 → 取對應點陣數據 → 顯示。核心需建立 Unicode 碼 → 字模索引 的映射表。
+-----------------+ +-----------------+ +-------------------+ | 漢字 Unicode 碼 | ==> | Unicode 碼表陣列 | ==> | 漢字字模數據陣列 | ==> 顯示輸出 +-----------------+ +-----------------+ +-------------------+
WideCharToMultiByte / MultiByteToWideChar
void UnicodeToGB2312(unsigned char* pOut, unsigned short uData) {
WideCharToMultiByte(CP_ACP, NULL, &uData, 1, pOut, sizeof(unsigned short), NULL, NULL);
}
void Gb2312ToUnicode(unsigned short* pOut, unsigned char* gbBuffer) {
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, gbBuffer, 2, pOut, 1);
}
CP_ACP:系統預設 ANSI 代碼頁 (中文環境為 GB2312/CP936)。MB_PRECOMPOSED:使用預組合字符。
/*-----------------------------------------------*
| GB2312 Unicode Table Constructor |
| author: Spark Song |
| date : 2005-11-18 |
\*-----------------------------------------------*/
#include
#include
void UnicodeToGB2312(unsigned char* pOut, unsigned short uData);
void Gb2312ToUnicode(unsigned short* pOut, unsigned char* gbBuffer);
void construct_unicode_table();
int main() { construct_unicode_table(); return 0; }
void construct_unicode_table() {
#define GB2312_MATRIX (94)
#define DELTA (0xA0)
#define FONT_ROW_BEGIN (16 + DELTA)
#define FONT_ROW_END (87 + DELTA)
#define FONT_COL_BEGIN (1 + DELTA)
#define FONT_COL_END (GB2312_MATRIX + DELTA)
#define FONT_TOTAL (72 * GB2312_MATRIX) // 72行 x 94列 = 6768字
int i, j;
unsigned char chr[2];
unsigned short uni;
unsigned short data[FONT_TOTAL] = {0};
int index = 0;
unsigned short buf;
// 1. 遍歷 GB2312 區位碼空間,轉換為 Unicode
for(i = FONT_ROW_BEGIN; i <= FONT_ROW_END; i++)
for(j = FONT_COL_BEGIN; j <= FONT_COL_END; j++) {
chr[0] = i; chr[1] = j;
Gb2312ToUnicode(&uni, chr);
data[index++] = uni;
}
// 2. 排序 (方便後續二分查找)
for(i = 0; i < index-1; i++)
for(j = i+1; j < index; j++)
if(data[i] > data[j]) {
buf = data[i]; data[i] = data[j]; data[j] = buf;
}
// 3. 輸出 C 陣列初始化代碼
printf("const unsigned short uni_table[]={\n");
for(i = 0; i < index; i++) {
uni = data[i];
UnicodeToGB2312(chr, uni);
printf(" 0x%.4X%s /* GB2312 Code: 0x%.2X%.2X ==> Row:%.2d Col:%.2d */\n",
uni, i==index-1?" ":",
chr[0], chr[1], chr[0]-DELTA, chr[1]-DELTA);
}
printf("};\n");
}
cl build_uni_table.c
build_uni_table.exe > report.txt
report.txt)
const unsigned short uni_table[]={
0x4E00, /* GB2312 Code: 0xD2BB ==> Row:50 Col:27 */
0x4E01, /* GB2312 Code: 0xB6A1 ==> Row:22 Col:01 */
0x4E03, /* GB2312 Code: 0xC6DF ==> Row:38 Col:63 */
0x4E07, /* GB2312 Code: 0xCDF2 ==> Row:45 Col:82 */
...
0x9F9F, /* GB2312 Code: 0xB9EA ==> Row:25 Col:74 */
0x9FA0, /* GB2312 Code: 0xD9DF ==> Row:57 Col:63 */
0xE810, /* GB2312 Code: 0xD7FA ==> Row:55 Col:90 */
0xE811, /* GB2312 Code: 0xD7FB ==> Row:55 Col:91 */
0xE812, /* GB2312 Code: 0xD7FC ==> Row:55 Col:92 */
0xE813, /* GB2312 Code: 0xD7FD ==> Row:55 Col:93 */
0xE814 /* GB2312 Code: 0xD7FE ==> Row:55 Col:94 */
};
uni_table 陣列複製至專案原始碼。uni_table 中二分查找 → 取得索引 index → 以 index 索引字模數據陣列 → 顯示。