|
BIG5到GB的转换技术 ) e2 [( ^! W8 z0 Y9 Y2 v. E0 o
; \ E2 f3 ^3 i+ _3 p7 ]
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
3 W# Z! k/ j1 c3 E2 R- L( i. {来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 + l* L) h- d* G& g
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 # p. ]0 t) e6 N* _4 { }
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 ( q0 C: K) j* y- L+ s" x6 \- i
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。
$ _8 Y8 e: f) q' m2 T8 b$ U$ Z 汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5 ) M- c% s! `# I- b: I
码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码
f; t' J! _) b' S! D, O% s4 I& ^2 q, g0 V(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
7 z) d: y, R6 J6 pBIG5编码对应GB编码的码表文件。 0 r* _) f" t7 m/ v: h# B
第一步 制作码表文件 ( k" `/ n) x( `) V. c( R
BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 - W5 T5 B! Q" Z3 @$ }! L8 c2 w
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
2 S, q1 x X# L/ G4 F8 e( c157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 ( [! ?# J* H% }
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 % f f0 j0 |: p+ D3 s" V) a8 I& A
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 4 u1 X: {6 `% R! U }
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 " w* y: g" d0 K8 o' {
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
; r: m0 y5 s V2 \,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 4 x8 |4 W; G# ^' ^# V
文件转换为GB码文件,即得到码表文件。 . s2 B4 `8 l8 W* P; Z1 ^
下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. / F. _4 R9 [- a; t6 I% J0 _0 O
TXT”。 : g8 ]7 {1 ~0 q7 f& K2 R
//TURBO C++ 3.0
9 M Z& I7 t1 _: M& _#include <Stdio.h> ( M% F7 u3 T8 X+ e& G/ l
#include <stdlib.h> 4 r x2 c" z; Z4 `% j/ @6 B) ?
void main(){ ! l2 p1 n9 {+ f1 E
FILE * codefile;
! W8 `, e5 a0 |; Xint i,j,k; ( [1 B1 Q9 D; w7 e( K. O
codefile=fopen("table.txt","w+b"); 7 W* B" ^% f8 {, a7 R" X
for (i=0xa1;i<=0xfe;I++){ 7 X' l+ ~. J/ H% n/ I
for(j=0x00;j<=0xff;j++){
0 Q. ^9 r- f9 G" z$ vfwrite(& i,1,1,codefile);
" F8 q: F; z/ d( ~6 nfwrite(& j,1,1,codefile);} 4 i' Z4 N2 K# V+ U# ^
}
~" e- S' i1 Y& z% nfclose(codefile);
: f2 y: V( B$ W7 M: I3 k* jreturn;
( S- i' B* G; f; R/ _} 0 h# o7 k4 `1 E+ r1 q3 p6 R
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, 5 @3 c+ {; O4 e8 ^ m
即获得码表文件。 + c- D, a/ S5 w+ Q0 l. a. C3 _
第二步 转换
& k' k u! z$ Q4 S- p9 V 下面的源程序,将BIG5码文件转换为GB码文件。
A- I) X% M% w, J4 U5 P" Z//TURBO C++3.0
0 i! n& ^6 K! i, N% {, n#include <stdio.h>
1 u1 _3 X5 K) b# v. J! j! o#include <stdlib.h>
4 ^- G+ [5 O& @; ?void main(){
& [- v( _6 }) }% Q2 d Eint que, wei;
( D! F: ]$ c0 Y% p4 pFILE * sourcefile; - f H+ ?0 L; _ k
FILE * tabfile; * x: j; [* V9 D( X9 @+ x
FILE * destfile; v2 G3 _5 | E6 k
sourcefile = fopen("big.txt', "r+b");
, W" T; Q' j1 v2 e//BIG5 码文件
z, T, X; _ u+ a$ D6 M; stabfile = fopen("table.txt", 'r+b"); 3 G& q. K5 r4 ^3 ~
//码表文件 / f1 o, h, X! Q& g. g5 y
destfile = fopen("gb.txt","w+b");
& d& l; ^: L' J7 t9 y6 g//转换生成的GB码文件
: {* M3 G: i/ C8 ?while (!feof(sourcefile)){ & ]! T8 Y& y' w* F9 O) m
fread(& que,1,1,sourcefile);
0 p2 H. A2 v3 J, tif (feof(sourcefile)){ ' I; C5 L* U5 @
break; }
1 R! ]7 L5 o8 m) Pif (que> =0xa1 && que <=0xfe)
2 q+ u) _% M! `0 p/ E, m$ [3 I" I//叛断是否汉字(BIG5编码) + u% {6 I w# A ]. h
{fread(& wei,1,1,sourcefile);
; V' u! b& p" X- ]if (wei<0xa1) wei = wei - 0x40; ! Y9 V3 k5 ^3 @* h" r( R0 E5 b
if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1; ' H6 X" E I$ n# ?% _+ E* _
fseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) 7 r c9 }$ h6 B! L' J, F5 h
+ wei), SEEK_SET);
1 Q% W$ i8 {& X* _fread(& que,1,1,tabfile); 0 I& h- t% f$ O! y, _$ j6 T
fread(& wei,1,1,tabfile); , d7 g3 p3 _4 T1 p7 k& g4 U5 U. i
fwrite(& que,1,1,destfile);
# P% ], m3 e; {: A3 c( O; pfwrite(& wei,1,1,destfile); $ f+ E9 r# {* b! Y
} $ a! n* e; `' m0 b7 p7 r
else
6 H$ _6 M- ]% g! ]4 |1 ]+ T+ dfwrite(& que,1,1,destfile); //处理英文 5 i3 |3 I. t1 D& u- l4 S- F5 O
} 8 H: V$ |0 l9 n8 G: F% t, T1 ]7 J4 @
fclose(sourcefile); ! b {( `; F5 L9 M7 _1 Y
fclose(tabfile);
( ?9 b" k) y6 Yfclose(destfile);
$ Y9 ^- L2 K6 Q5 ereturn; 1 K% K" L5 \. k8 S
}
4 s! _: C" i3 u* ]4 b4 S 以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用
2 J* j% s7 H( m" C0 e同样的方法,我们也可以将GB码转换为BIG5码。 |