|
BIG5到GB的转换技术 W' G* F( s6 ]6 s! U: g1 g
) L* B, f0 c1 C+ J6 m. T
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
3 p0 S* ^5 s% `( ?- e& g/ E8 ?来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 1 g$ k" D3 R2 x
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 % ~9 m3 }4 A1 I& q4 r
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 6 V; p3 D* w& F% m3 q" A1 @. C' d
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。
. M3 z- L' p/ ? 汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5 % O4 f6 H1 J$ ^1 D
码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码
1 k3 Y. w/ S7 M$ X(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个 : w( q5 G H1 k9 L2 ~
BIG5编码对应GB编码的码表文件。 3 h, [ x3 l* K
第一步 制作码表文件
& `3 I- t: z% @# n- o* C BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 ) H. j: N$ m3 I
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
) `% Y9 i- G: J+ _0 ^. d1 x157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些
H6 _8 O% L5 N汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 + T9 ?/ {" W/ f: w- X% x
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用
/ g0 R- s4 t. p `字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。
* o" f6 [& K3 Q, y8 I" W 制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
! t R2 q7 b/ r,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 ( O& v }2 i: D% C
文件转换为GB码文件,即得到码表文件。
' {$ t. E% m% d4 e 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. 8 {3 x6 h2 [7 P/ I G
TXT”。 $ |- P4 [1 P" ], D6 s" }" Q
//TURBO C++ 3.0
: g. U! J4 b; O9 [* B6 f# Y( x#include <Stdio.h> ' A8 n. D& _7 k) [) o& D4 R6 ]; m' S
#include <stdlib.h>
- Z! }6 ]8 x/ ^- H9 n- P) I2 }void main(){ 5 ~& C( P1 [: m* ~9 ] d/ j* D
FILE * codefile;
1 _; w) e, N$ E+ z$ {: H8 Gint i,j,k;
- u5 p0 u! O5 g5 g9 p% `1 m- R6 Kcodefile=fopen("table.txt","w+b"); ! z2 v9 \7 H0 c3 g! Y7 M. V
for (i=0xa1;i<=0xfe;I++){
9 z+ ?, f, J; L" }for(j=0x00;j<=0xff;j++){ g- _ s7 g6 |& J( C
fwrite(& i,1,1,codefile); 8 w8 n8 J. s& F( D. S7 A- i
fwrite(& j,1,1,codefile);}
3 R$ Q1 I; _+ z; [7 F}
! p! z. e0 {; `fclose(codefile);
5 g5 P! D3 h+ s* Areturn; ' ~. f" H% ~) a( y! k7 u
} 3 k( e, \4 p- |0 J# i
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, 4 }' f6 o, R$ Y b' n/ _; J( {
即获得码表文件。
2 {; B1 ~! Z+ a1 X第二步 转换 : i& ]6 O# \5 y2 G; j9 Z4 q
下面的源程序,将BIG5码文件转换为GB码文件。
4 G* Z4 w2 E* \- J; _//TURBO C++3.0 2 I6 j$ O2 v' S9 j8 B4 U; q6 S
#include <stdio.h> * u+ D; Q! K, h3 j
#include <stdlib.h> - c4 j4 X: V, \# y4 [! i5 I! \
void main(){ " H% i: W0 }( b# \8 t
int que, wei;
& K' s" ~" @) g) YFILE * sourcefile; N& p/ V6 U! j+ p e4 L" J6 Q
FILE * tabfile; 5 a7 n; [- L6 M7 }
FILE * destfile; + L% C, b; c8 s) Z7 X, T. b# s
sourcefile = fopen("big.txt', "r+b");
& l, y9 n2 }3 V; j//BIG5 码文件 7 J! W) e8 {- Z2 p3 ~: }
tabfile = fopen("table.txt", 'r+b");
: @ P5 z$ `, h0 ] b//码表文件
; n/ C) r% q; {! Z0 h! N8 ddestfile = fopen("gb.txt","w+b");
8 d# Z; O7 r C& \//转换生成的GB码文件 / k) z; M6 Y5 s* {! C& L4 Y
while (!feof(sourcefile)){
% C. R4 X7 L; W# {1 }. ~3 Rfread(& que,1,1,sourcefile);
2 s# s9 }% a& Bif (feof(sourcefile)){ ' R! D6 C% x K. t; w0 ?: U
break; } ( [0 N3 i$ C) i3 D
if (que> =0xa1 && que <=0xfe) / x& u4 t& s R+ ?% J
//叛断是否汉字(BIG5编码) 3 Z" `( j6 m) T" Z' _
{fread(& wei,1,1,sourcefile);
4 G z4 t5 X d& b0 kif (wei<0xa1) wei = wei - 0x40;
+ C- \: n0 f6 i$ D- {" y1 Kif (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1; * @# S% b" a8 X$ s0 q9 k9 t
fseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) , _ z# V8 ^* G' i% S- u# l
+ wei), SEEK_SET); 4 ^& y R& A# I G% ?9 F+ ]" o
fread(& que,1,1,tabfile); ) w* b5 p! c! V8 I& s6 |
fread(& wei,1,1,tabfile); 1 j& J% M: q# y; Q- {
fwrite(& que,1,1,destfile);
4 h9 K" R0 i3 H. y2 ~1 Z: ^5 y; |, ffwrite(& wei,1,1,destfile);
; h, t3 I- |7 E}
}5 l% F7 A" n# x9 Lelse
/ m! A$ J) e; ^6 R! {) ifwrite(& que,1,1,destfile); //处理英文
0 @8 R0 X+ L( z" v: b0 C' a}
x2 M1 l |9 ~; s" xfclose(sourcefile);
) V2 b7 k" M0 W8 p: \/ b. Afclose(tabfile); : a( F( Q0 T% H6 e
fclose(destfile); 8 _! j! _) _5 O0 d
return; $ ^, g9 h& Z0 _1 ~4 \$ b
} 4 l/ s% M* C% Y% h9 p% U% C" ?
以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用
' v( a$ m0 c; D1 u同样的方法,我们也可以将GB码转换为BIG5码。 |