|
BIG5到GB的转换技术 5 }. z* F, X, V4 R) P
. E$ r3 I, t$ D* d; i0 B0 k
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节 # M) K# y% q, O( }9 Q
来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置
i. P# s9 F: R0 s0 a) R9 b" _。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 : P. B* M" w- F- k; U( Y/ a7 B
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 7 p( I& B- h0 p/ O# h5 b8 J% o+ i
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。
) `6 J4 n. f8 b9 K 汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5 1 k( Q( O' G2 F: d9 G
码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 & m1 N8 p) E, y
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
5 J. _# } y- h) Y3 w) s. d4 PBIG5编码对应GB编码的码表文件。
, C+ g( `! i8 ~0 E$ F! w- V第一步 制作码表文件
* F) Y0 Z1 z8 M! t8 ^' d j0 N BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 9 ~' B3 V; t7 t1 O9 o1 H
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共 $ J: `' F/ h y- j& C
157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 $ u( r! y, e' k! ]
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 - I! _* q2 y" l! r+ [& e
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 % } _0 t: U* p
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 , L: `& ~. r+ }8 p' I
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
( w- b! }; n- k& o; a" |" O,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 8 S9 V4 Z3 E9 k0 R$ C# v
文件转换为GB码文件,即得到码表文件。
9 ]) N# ?& i9 h0 k7 q% b! i, O 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table.
/ j+ y( c& r% O l4 L4 [3 tTXT”。 ( w l9 v$ b1 U2 \9 D, i$ N: g
//TURBO C++ 3.0 2 m% Z$ ?7 X5 X4 `% E+ M" d
#include <Stdio.h>
0 G% e& u% h) U6 @2 M#include <stdlib.h> 3 U2 K% ^9 x6 W, L7 _/ c2 Z+ U9 }
void main(){ ( U; H0 i3 M5 y. m
FILE * codefile; ! r3 X' F7 u5 w& q9 z
int i,j,k; 6 z4 x# p. Y8 x- s3 T1 `% `- L8 R
codefile=fopen("table.txt","w+b");
# Q2 O$ }6 K! T* M$ v' L* ]for (i=0xa1;i<=0xfe;I++){
6 ` k' _8 Q- n" v9 f& Kfor(j=0x00;j<=0xff;j++){
4 k+ H% h2 @5 ?( }& \& j( {fwrite(& i,1,1,codefile);
2 V+ T6 Y' ^2 I) d) H9 b" O! k/ vfwrite(& j,1,1,codefile);}
% b( H# v4 ~5 _) U, s# q, W( X} + C' M% ~6 i4 \4 ?# o, Z" h
fclose(codefile); 0 c- \9 Z; E1 Y9 o$ b4 ]
return;
6 ?$ S' D, _" u9 X2 v} 3 O! e. S: q) J. h+ z$ M
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码,
1 n3 f R" s! a- M8 v& W即获得码表文件。
9 U$ n9 a* U* N第二步 转换
3 O% h" [" J# A$ z 下面的源程序,将BIG5码文件转换为GB码文件。
+ l* Y6 v% B1 K/ {0 U//TURBO C++3.0
9 a( R8 W' i$ f#include <stdio.h>
% D( {( F5 M! a5 N8 } [#include <stdlib.h>
2 O; ]5 S. M; K2 Kvoid main(){
$ r, g% _* W' vint que, wei; 4 N( T+ b) C) ~
FILE * sourcefile; X& I* a; L* T& K0 w7 `; d
FILE * tabfile;
: m0 K" C. p6 O. J) MFILE * destfile;
" z |: i( I0 f& k) k, B6 asourcefile = fopen("big.txt', "r+b");
! a) C7 `/ |( o6 f2 S; S//BIG5 码文件 3 d: U3 S! g9 v$ I& e* G( q2 A$ _1 \
tabfile = fopen("table.txt", 'r+b");
6 u& K/ E' N% r5 }& K$ ~; x7 M* W//码表文件 " Q+ B2 M" i) l/ E9 I1 F
destfile = fopen("gb.txt","w+b");
" U1 J" t! b5 I0 R, g//转换生成的GB码文件
: i% D+ O) }. a! A, f7 Pwhile (!feof(sourcefile)){ - n! ~8 s+ ~8 U, A: ?+ ^
fread(& que,1,1,sourcefile); , Z) t% R# k* m
if (feof(sourcefile)){
8 h* D3 a5 a& a* ?+ ?break; } % ^) k: T/ I7 D& v0 V; f9 C# {
if (que> =0xa1 && que <=0xfe) / y# W# d& Z# v& B, K
//叛断是否汉字(BIG5编码) 8 D% G9 ]2 K* }8 c/ K5 ~
{fread(& wei,1,1,sourcefile);
) l8 A6 n4 d N- N* g1 _if (wei<0xa1) wei = wei - 0x40; 4 D, f8 y; O7 ~. u
if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1;
7 g" k. d1 `2 [7 `' `9 Afseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 )
1 z @& }: I' q# k- Y' z! K7 A + wei), SEEK_SET); 6 n# P [5 f( I: t* i+ e1 G+ x% [
fread(& que,1,1,tabfile); . d7 O0 z) }% m2 \, b5 g' d+ ^
fread(& wei,1,1,tabfile);
) i5 T& l& i; |8 ?" n" o9 h2 ?fwrite(& que,1,1,destfile); 4 F9 J& D# c4 j! b
fwrite(& wei,1,1,destfile); ' {# ~. D; |1 C/ ]$ f1 G& f! `
} & R, V. [' e' {- s# I2 ?3 q
else * m& A( h) S. m7 u7 ^; F
fwrite(& que,1,1,destfile); //处理英文 " T& w+ C, f, J7 T9 J
} 9 E \% c' N- w9 L6 S2 E2 l
fclose(sourcefile);
K5 ]1 M4 s0 r/ C3 Bfclose(tabfile); 4 f6 I$ n8 I c. u7 h% Q4 w
fclose(destfile); : Y0 ~ }9 `9 U* ] ~+ ?" ?% ~. g
return;
U8 i+ f7 d9 L# A' ~$ k/ y} 3 O" w- Q; Z* r1 d- q3 H
以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用 - L+ l4 ?- ], o) v* M9 S6 N! t
同样的方法,我们也可以将GB码转换为BIG5码。 |