|
BIG5到GB的转换技术
6 z* B8 x& n6 u: F1 M- r& p% e, ~* T
# j: k* O- G: x; t0 R中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节 9 x6 U5 f: `9 u7 h
来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 / `- V& W( N) S
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 & h( n+ ?: X3 u. k1 K9 y w
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 / W" }! l: D/ U
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。 ' ^/ p) J! R% H! l) t
汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5 $ Y6 B9 O+ _" T- K
码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 + ?" r2 u8 V |
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
9 l |8 O2 ]/ Y3 E0 nBIG5编码对应GB编码的码表文件。
2 f+ c% F% J: D) _- A+ a h第一步 制作码表文件
7 n. A7 @+ _* ?# q2 }3 D BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 6 P, w3 q" r: N( F7 g8 N+ b
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共 $ u- C/ ]0 k/ J
157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些
: O! H C% J0 U0 m, J汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的
) q; l- y3 y4 \( @' W7 u6 t范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 $ c9 q2 C7 [' ]- v, T0 N8 a" H
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。
2 i# y! @7 b7 C 制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
( \% k- ?% V. y. @3 I7 f,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将
- v6 `" b6 @6 F( ?8 G文件转换为GB码文件,即得到码表文件。
1 _: D B" x. ? 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. 8 T- G h' c; x) x
TXT”。
: n( u: v' f& t4 Y u//TURBO C++ 3.0 7 c! K1 P1 j4 y) B. N
#include <Stdio.h> ( t! D% r9 F; h: Y0 {) @9 `5 }
#include <stdlib.h> ! x. X9 n4 U5 K3 T/ P- v6 D
void main(){
" \% A0 ~$ T/ p6 gFILE * codefile; T! E& F; b2 P& u, a' w6 h7 e
int i,j,k; 7 w$ G& n9 V9 T- u
codefile=fopen("table.txt","w+b");
f5 R# X% z7 o% v. J( A+ [; m* D) `7 Yfor (i=0xa1;i<=0xfe;I++){ 0 T6 _- h& N8 z. k" H& S L
for(j=0x00;j<=0xff;j++){
1 k" }) V" ~ ?$ {, |fwrite(& i,1,1,codefile);
3 E! F; }$ H/ x% P. Z6 U0 afwrite(& j,1,1,codefile);}
0 \; X2 l5 B$ J}
) b W" K; Q6 g3 I9 u0 Zfclose(codefile);
8 B" ~) R# M( zreturn; : j( R/ F" U( K! V0 R: m8 q7 g
} . h( _3 a4 d( X
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, " R/ d+ V3 S" x# b
即获得码表文件。
1 ~! Z. X8 s5 L& ?! P第二步 转换 ' k) \6 x5 v1 U' O: r
下面的源程序,将BIG5码文件转换为GB码文件。
' W7 w2 r* b8 ~# Q: e//TURBO C++3.0 3 V2 |& @. s I5 V* H! E% @
#include <stdio.h> : S' @& h) R, g- J' g" K* w- r5 o
#include <stdlib.h>
; i3 a6 k( d% _, Dvoid main(){ # ^9 B5 V: c; w2 y
int que, wei; ) S/ R) n9 o8 Q# F" h# g' A
FILE * sourcefile; 8 T2 \ P6 d& ~) G( G
FILE * tabfile; 9 o6 V* I- f4 X) c
FILE * destfile;
) b: J2 ?7 \4 n3 ~: msourcefile = fopen("big.txt', "r+b");
; q, ]% ^; L9 Y+ ~4 n4 r/ L//BIG5 码文件 : p' [3 {$ a* c% } e7 L7 g
tabfile = fopen("table.txt", 'r+b");
. `7 l# w$ j) P' ~1 T. ]//码表文件 6 t* V5 L' g6 v2 g; d1 |; S$ h; b
destfile = fopen("gb.txt","w+b");
% h2 {- S( a4 H* g7 f//转换生成的GB码文件 & b- U$ P$ W( h) y# Q6 {" g5 n
while (!feof(sourcefile)){
2 U/ ~. N7 I9 g. w+ u; Q9 n0 ]fread(& que,1,1,sourcefile); 1 w" a: f; a; Y( A* n
if (feof(sourcefile)){ 3 x \" _, G' x5 v+ C" Z
break; } ( U3 p& ~1 V" U& f Z* ? i# f
if (que> =0xa1 && que <=0xfe) , h$ ], \" {; }
//叛断是否汉字(BIG5编码) 6 j9 l/ ?. f5 e; {
{fread(& wei,1,1,sourcefile);
$ Q1 A8 ]% T0 uif (wei<0xa1) wei = wei - 0x40;
# n& ^* n' X2 z5 P. O: _! b" {if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1; 6 J5 ^; e. B r/ v7 W. a
fseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) , n6 `8 C) f$ T, e* ]
+ wei), SEEK_SET);
# c: e5 ]' g* h: K* _fread(& que,1,1,tabfile);
2 x' c; }/ z$ J& @fread(& wei,1,1,tabfile); 7 B* Z2 O! c. Q0 Q: @
fwrite(& que,1,1,destfile); 6 z# f9 y- o# @0 [- M5 R9 ~& j
fwrite(& wei,1,1,destfile); : J% W1 g' ]- N2 H! u
} 2 K9 W4 F4 G* Z
else - x4 p: U4 y" o& u3 A8 t2 ?- U
fwrite(& que,1,1,destfile); //处理英文 - \! F; B' ]" X+ z
}
# D5 d ~) G' A( Dfclose(sourcefile); ! Q- W+ e6 p0 Z7 F3 ]
fclose(tabfile); & {* ~4 N) ?1 U& V: Q
fclose(destfile); |7 }" f# D" {0 o, Q
return; ! C* D4 l( z& k/ M
} c, D& t( U, R' a3 |) }
以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用 ; b( R. @4 d0 s1 b U. f" [4 y1 }
同样的方法,我们也可以将GB码转换为BIG5码。 |