|
BIG5到GB的转换技术
1 I% c+ x7 [. u
& w% w* d0 g% \4 h2 h! b中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节 + ]/ g# w" X8 m# x% M5 W5 Z4 `! u
来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 + D/ ^) s7 n" I8 X- U
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 ( G8 Z) K( [/ A- k2 P2 ?
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 ( N& L$ G2 F4 y7 g! h' @6 m8 O+ j
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。 & _2 B* o. {! g+ }6 H G, Z
汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
' c8 i4 G3 N! W3 q3 E码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 $ F- Y. g0 q4 P; k/ W
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个 5 ~' k' E7 y9 _! s- S3 S1 L" ^1 a- N) G2 y
BIG5编码对应GB编码的码表文件。
* |- I2 [8 H) z( _+ v a第一步 制作码表文件 6 g+ \2 q3 N5 e# m
BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 % i) K' u2 Y8 H6 G" [% J {. w
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共 I. K. o: z/ O I3 e" B$ e
157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 & ~7 d/ w, C, `4 u$ m# ^
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 3 q: @& A$ B" |7 b+ D; g% V% d
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 " p5 p1 h( [* z/ `
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。
h# M" V5 e! `- } 制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后 3 Y1 Z" j$ ~4 _9 e: t5 ?
,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将
0 [8 J; o( L; \7 S% X文件转换为GB码文件,即得到码表文件。
6 V' B5 I# {0 h) n% T+ Q 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. 2 P# m$ N: F4 x! v( ~) a: w
TXT”。
) q% b' k1 q# Y2 X3 x+ |' @//TURBO C++ 3.0
+ A7 G C/ P, y @#include <Stdio.h>
* D0 l: \/ w; h3 @8 \ k4 H#include <stdlib.h>
: j+ L5 T$ W9 q# K( Y- qvoid main(){ + L( D2 v2 ^# B
FILE * codefile; / t# \2 W0 ~, |8 \: J; x
int i,j,k;
& R/ d8 y ?# kcodefile=fopen("table.txt","w+b");
# ]2 j1 K1 u2 f2 d S2 h6 ?for (i=0xa1;i<=0xfe;I++){ . q, ?% U) r: |. N
for(j=0x00;j<=0xff;j++){ ' R3 x2 k6 U7 }; t
fwrite(& i,1,1,codefile); 8 P5 b% ^! G& b" F( s; S0 W5 A% M
fwrite(& j,1,1,codefile);}
) H6 n( |& F: H6 f, B} / E1 m; J0 j [" T# U1 j' f
fclose(codefile);
3 X, N2 B$ ]$ s! greturn;
& n0 P! P' w+ `* |0 ]} ) {. \- C. a( k- D& @' s. }
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, , ~/ ~. v# u7 R( U9 d/ c* A8 K9 \- L
即获得码表文件。 / P3 ?/ K2 f5 |5 R6 J( A
第二步 转换
# F+ K. |! v; r7 y 下面的源程序,将BIG5码文件转换为GB码文件。 3 b2 ^* k7 N" g+ X' @* v9 T. B& G
//TURBO C++3.0
' {0 \* [, W; p#include <stdio.h>
G R7 `. O7 w b4 y* R#include <stdlib.h>
' g1 v* ?8 m9 o: ?. R% R0 R; W6 dvoid main(){
* _" m6 S. S1 D# p+ gint que, wei;
/ w, D$ {' w9 e+ B0 U4 L# J, yFILE * sourcefile;
% ^+ H; ]: V+ p3 }- m2 G0 @& PFILE * tabfile; o# y f. ]9 s3 N* _" c+ U
FILE * destfile; . Q! d9 Z8 ?5 Y% B0 n) e2 _3 t" g
sourcefile = fopen("big.txt', "r+b"); 8 u9 A2 `! z% j5 U
//BIG5 码文件
5 L4 V1 M( k1 E% r/ H* [( ?" E4 mtabfile = fopen("table.txt", 'r+b"); ' ~7 J( h1 \- `
//码表文件
9 C/ Q; D; g. m& Vdestfile = fopen("gb.txt","w+b");
$ e) v0 M# d$ Y0 z& H//转换生成的GB码文件 0 W8 ~0 Z0 k* H6 |
while (!feof(sourcefile)){ # A m. p! W2 A% C
fread(& que,1,1,sourcefile); ' ~ W/ D: _, Q
if (feof(sourcefile)){
: ]2 [6 |9 ]' |- I: s) F8 hbreak; }
" c9 S" C; \+ o5 i$ _if (que> =0xa1 && que <=0xfe) 7 a* J' m/ c* L% l7 ]
//叛断是否汉字(BIG5编码)
2 b* t& y9 S' y! E" ]4 v. @9 d{fread(& wei,1,1,sourcefile); * p, y/ J+ @' k- X% t
if (wei<0xa1) wei = wei - 0x40;
! p8 P7 }0 t) }7 L8 v5 G3 X. I3 V0 mif (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1;
1 {9 t* a# p8 R r+ p3 N( c* Ofseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) : M3 o9 t/ ]9 Y- H* M
+ wei), SEEK_SET);
$ R( {0 v9 \0 V, Ofread(& que,1,1,tabfile); 0 p, U" o l+ W. e/ U
fread(& wei,1,1,tabfile);
9 ?$ d/ q! i5 Y, T- R2 X: Mfwrite(& que,1,1,destfile); 9 v1 [; z( v% M: d" k6 p1 s
fwrite(& wei,1,1,destfile);
3 o. ]: {. r6 o} & J/ O( k! I9 @ D) N q+ e
else " o1 k/ V* s1 Y
fwrite(& que,1,1,destfile); //处理英文 ' i' N0 r; Q5 O; y# P0 d2 z
}
5 V% Y& ] q: [" v5 b4 m9 Pfclose(sourcefile); 8 {1 w u4 X( c& ?6 w% C
fclose(tabfile);
4 L0 b5 i2 k7 nfclose(destfile);
$ e$ z, Y6 M1 A! k B0 _7 t! [return; ' }# Q4 G' `% C
}
5 ~7 v9 h8 @1 d0 ]3 x. { r 以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用
2 K# b* X' W+ \3 m# d- _同样的方法,我们也可以将GB码转换为BIG5码。 |