|
BIG5到GB的转换技术 ; v7 ^+ v: y! T- `3 V' y
- V7 u$ U+ k3 v/ U
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
3 G4 S+ s) W3 J6 s来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 ) G4 m' ]% P! L; N% A
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 % c8 k& S5 t% C; g" X) q
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 - ^% g }* G, x7 j: ]; w7 U
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。
$ O! c+ o, F @ O# L 汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
+ V' F% `. r+ G+ t, K4 K7 j码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 - s N4 Z5 P) c$ T
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个 - M7 B# v1 G2 a+ A. t8 t* J' W$ D
BIG5编码对应GB编码的码表文件。
8 Q9 C7 `) h* M6 x8 K# ~第一步 制作码表文件
/ x; w; \8 t( H; ~2 h4 D1 f BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从
* G |9 G) X/ b7 ?0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
( N: M1 d' {4 a157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 " l* R. C, f6 T3 W4 }. D p
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 & h6 p- t4 S1 r- z
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用
" M W( _. _3 t' f- P0 o0 k字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 ; N% q2 S2 ^* Y3 \
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
& e. Z3 g. d! ~/ o" u# X5 }# N2 R$ k1 w% B,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 . g1 [' A, i/ W* E T3 w0 O5 Z
文件转换为GB码文件,即得到码表文件。 ( J9 w( T( y2 W1 \% O* u9 f, Z0 U! R
下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. . z- o$ p) S$ {: V& O8 b5 \) q
TXT”。
5 {4 c+ D; G' k//TURBO C++ 3.0
$ z/ L- B; }3 u! k, S: {1 ] H#include <Stdio.h> 0 d( f9 O& Q+ f9 Y
#include <stdlib.h> ; D& w6 F; m5 v" T- f3 l
void main(){
* E2 M: h. N+ _FILE * codefile;
, ?/ H: L' B; ^* N% \1 xint i,j,k;
! ~7 K# {. D! |0 C6 `' Gcodefile=fopen("table.txt","w+b"); $ n8 N |; n, U$ ], ^' l
for (i=0xa1;i<=0xfe;I++){
: w% m; P3 C& m- u; ^for(j=0x00;j<=0xff;j++){ ; T% N; d, w8 o- W" ?7 X
fwrite(& i,1,1,codefile); 7 E1 W. O5 h1 f9 ^/ v. D3 K
fwrite(& j,1,1,codefile);} 1 Y. I S- R1 t3 ~5 T1 w i3 o
}
5 X% s: J0 h2 ^- Y0 S( {0 Ufclose(codefile); * H0 P* V. N, ^0 J* A, x0 z
return;
- r5 h# Z2 G# @ ~% k" w/ T}
% q0 r1 h. w0 G+ s2 v5 @( c 运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码,
( @ D; {% ~" U1 A9 C( e3 g即获得码表文件。
( h5 `7 b0 @9 c第二步 转换
" r0 n* S$ A/ ?$ d( } 下面的源程序,将BIG5码文件转换为GB码文件。 g) G# q; {% @4 {6 d/ f V
//TURBO C++3.0
. j0 `8 Y, t$ |& O8 w#include <stdio.h>
- v7 B, Y: K P! t- s. h' h#include <stdlib.h> 2 t& V' N& b3 ]
void main(){ 0 I8 U) E$ P' |( W6 T8 z
int que, wei; $ V' L6 t- F$ U
FILE * sourcefile;
6 X, Y4 k+ E( g: n4 n% Z# ~" k( OFILE * tabfile;
: N- J/ Q9 X5 f% e# h9 K" U* HFILE * destfile;
& L' D7 \/ T9 M$ `sourcefile = fopen("big.txt', "r+b"); + D) V) O) Z$ _" v( `: s4 d2 u/ Z
//BIG5 码文件 4 y) t1 Q; F! g% t" M
tabfile = fopen("table.txt", 'r+b");
% A$ \: k) d/ u- j% e//码表文件 2 A$ b7 x3 B2 F9 V% o& o
destfile = fopen("gb.txt","w+b"); ( u' B& h3 [" m0 o/ ^
//转换生成的GB码文件 5 k( Q! u0 S( R9 N. E3 T3 t, {) {& X
while (!feof(sourcefile)){
( s% t5 I% ~+ P nfread(& que,1,1,sourcefile); 3 C! h3 {- h- j3 x: ]) _; J
if (feof(sourcefile)){ ( A: J) ?( P# f. U% m1 G( n
break; }
0 S$ I8 Q# x/ W0 t; B) k+ t9 A( bif (que> =0xa1 && que <=0xfe)
+ d/ Z# x _% _; l0 j/ J, |//叛断是否汉字(BIG5编码) 2 y! R5 f$ J: o% f: b
{fread(& wei,1,1,sourcefile);
0 ^" D6 ~, k3 j4 w5 } i& |if (wei<0xa1) wei = wei - 0x40; & j% B% ]7 B2 c) L1 a
if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1;
/ b V5 P I/ Ifseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) , Y7 K8 C3 ^5 V6 b, i# P
+ wei), SEEK_SET); - t% G1 M5 M1 k2 g; A
fread(& que,1,1,tabfile);
8 D; B: r5 j- v$ v2 M% X* cfread(& wei,1,1,tabfile);
2 E+ n/ N% Z0 P8 A" }7 K) ~/ u; ufwrite(& que,1,1,destfile); 5 B5 {- S. N( ?# W
fwrite(& wei,1,1,destfile);
7 i8 T! G6 v7 ^* N2 \2 ?0 }} & l1 [7 b- H# c2 s' W5 A# ?
else $ S3 q* q$ u6 i& O) \0 B
fwrite(& que,1,1,destfile); //处理英文 % T# }6 K8 I% n$ w! C
}
7 Y! ]+ I1 N/ h+ V3 ufclose(sourcefile);
" G2 a, Y) Q; a# t9 y! Q) p3 hfclose(tabfile); / W( K0 i' d* T1 X8 Q, M; c
fclose(destfile);
2 }; e% U/ ^; F0 Ereturn;
4 ~2 r2 D+ [. d1 d* y0 }}
1 V. V; R$ Q5 n) g: R% j( w 以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用 / A/ D' w" D' R# |# v2 }
同样的方法,我们也可以将GB码转换为BIG5码。 |