|
BIG5到GB的转换技术
/ |/ s. r/ O; @8 Z. g - P3 e* J8 U" F5 K7 ?6 n! K# [! h
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节 , w1 \0 l5 R9 p* P9 i
来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 * a: N' ~9 ]/ K% O d
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就
5 }1 c3 S; u/ J可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个
8 c, C) M2 {" y- }- V" u6 S汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。
! _$ a. K9 p$ H8 x# g v3 p W7 w 汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5 ! h# A W, r1 X4 B6 F
码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 ' v4 t9 r4 Y: X6 C
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个 8 _: I! T, p. p: k3 V; J. ]
BIG5编码对应GB编码的码表文件。 ( \4 Y5 c" K# V' n9 x1 e8 m3 A
第一步 制作码表文件 I! A9 e' n2 y6 `1 f
BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 8 k7 `3 N1 @! ~: ^
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
- v# l8 w: E; h/ T157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 ; U4 @' G6 N& i L. o) m
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的
7 I0 T/ U% ^" I u范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用
+ V7 C2 g0 n' ^8 D字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。
# H$ _% B3 Y7 f5 N 制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后 ! |! g9 e% l& t# \
,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 ' Y: ^& b& i0 C
文件转换为GB码文件,即得到码表文件。 & M6 K5 s+ i/ ^0 F& S
下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table.
& T3 f% i, P# Q3 y& g ^* WTXT”。
; K+ L" `+ ~0 n5 ?* \6 A1 v//TURBO C++ 3.0
( W% v8 d' ]" e, \" R#include <Stdio.h> 0 M/ U; V. t; K/ c* Y! G
#include <stdlib.h>
8 ~: u; a' I5 _0 Y6 M8 M6 q1 L svoid main(){
& L4 b0 ^( ?2 q, W( eFILE * codefile;
# K2 q# e3 ~% i yint i,j,k; 4 G3 g5 G7 l2 c7 v
codefile=fopen("table.txt","w+b"); 3 u0 Z: h0 H8 {- M
for (i=0xa1;i<=0xfe;I++){ 3 K9 Z7 `9 c& ]. k/ x( w, |! Q
for(j=0x00;j<=0xff;j++){ . U* x! V6 Y9 H8 D( O
fwrite(& i,1,1,codefile);
( A* o, v% Q" ?; j! {; T Yfwrite(& j,1,1,codefile);}
* S$ d+ r! j. T" O/ X1 P}
9 T9 {& a, [9 _6 tfclose(codefile);
5 ], ~/ h+ j9 o! ?* E3 preturn;
# i8 \% y; z: K/ H) K}
0 r' S" S! v6 F* L) L 运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, $ b& Z6 C# ?$ a8 F, t: W" S
即获得码表文件。
) b2 G3 R1 V) Q* p. I" [9 @% Z第二步 转换
C6 r# f: q5 S2 W2 J7 a 下面的源程序,将BIG5码文件转换为GB码文件。
" V( M$ n) k; w" u//TURBO C++3.0 6 w# P& R+ I& l0 Y8 `! E+ Q
#include <stdio.h> " t2 Q$ i1 P5 f0 L4 ^4 U
#include <stdlib.h> 3 y1 K4 Z4 W& \# _% P. z0 R x0 R
void main(){
; \$ R5 X$ d/ n: Uint que, wei; $ G6 K9 t [7 h& n, y" i' o& f) @
FILE * sourcefile; ) B. L; n! v5 N3 k* s
FILE * tabfile; 8 m, O ?) U9 ~/ f% b
FILE * destfile;
, L; H5 \, Y* {: Isourcefile = fopen("big.txt', "r+b"); ( a* L: C2 d( f8 O; _3 _# K
//BIG5 码文件 9 W; O: q1 x( P+ r
tabfile = fopen("table.txt", 'r+b");
4 p# s1 u' M, p$ \" o//码表文件 ! n% _( v) @/ {( {
destfile = fopen("gb.txt","w+b");
5 j* o" _9 ~4 K: X& X9 @6 y$ t//转换生成的GB码文件 " G# W( I( w) C
while (!feof(sourcefile)){ $ p Y7 k1 \6 q
fread(& que,1,1,sourcefile); 9 F- _% d6 B( y* f" \
if (feof(sourcefile)){ : u0 R0 v9 u, Q$ g
break; }
) d: z$ o) _9 j0 ?; W! kif (que> =0xa1 && que <=0xfe) 0 J1 S# h: u3 ]) y4 l) k
//叛断是否汉字(BIG5编码) ) I. ]) w4 }; y1 |/ x m( ^
{fread(& wei,1,1,sourcefile); $ n( y* g! b2 j, U/ l
if (wei<0xa1) wei = wei - 0x40;
. H9 j2 h3 q. V2 `if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1;
/ M- g3 r H1 w* g7 e) M1 Lfseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 )
6 M- q0 q4 l ]! x2 K + wei), SEEK_SET); : l4 M" N' F% H3 ?
fread(& que,1,1,tabfile);
0 s$ u& f" ?) q5 {# U6 ]fread(& wei,1,1,tabfile); 2 a) Y. _0 Q _* d' T; [9 T
fwrite(& que,1,1,destfile);
' }$ O& V( i8 W& Tfwrite(& wei,1,1,destfile);
4 O! ?( ~- v7 `4 d' W} # x: b3 }5 f5 u. o' f3 Z
else , r, G2 f2 L: j( H* H2 V4 S
fwrite(& que,1,1,destfile); //处理英文
+ x# @. M4 Q6 l5 c7 |. | a* H7 H! F}
8 l. D8 x, Z4 w* Y" y2 s' m3 M4 nfclose(sourcefile);
! L. a+ Q7 S! W H* X$ ?fclose(tabfile);
; I6 `) X, g: S# Qfclose(destfile); , c) D- z7 d0 p; [
return; / a2 J7 |8 ?$ }2 z7 ^: d8 Y
} Q4 {5 i5 x' p8 w" C9 Y
以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用 # Z8 y% W& c7 Z3 s" n$ }
同样的方法,我们也可以将GB码转换为BIG5码。 |