|
BIG5到GB的转换技术 9 r# ~: p/ E" P" P) k
" ?) K- y& |! E$ R( x9 u: m, v( s中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
# D8 k6 v; `6 A7 ] u: ^7 }来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置
{8 [. C2 U: W- F7 C。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就
9 e& I, s8 O9 q# `! w1 _6 u可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 * m1 X- y3 b: }# C! \& t4 [2 {* D1 v
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。 7 I& t. u* N6 {2 s' e5 Y& [$ l3 i
汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
9 h) _. ]$ f! ^' n* R5 c码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 7 L% }2 d; H+ z9 @2 d1 K7 C, b
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
1 ~' T, ]; H# }7 }% f C* n; yBIG5编码对应GB编码的码表文件。 , ?, k$ y- U: {
第一步 制作码表文件
2 H; W( S" ?- L! t# u6 b/ ^# e) M BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 ! _* |" L/ |! L5 N
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
2 ^6 r4 \( W: I8 \4 E$ D0 _7 k157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 - s! N8 Y0 `3 `; v0 l' o! B/ R
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 % R$ F2 Y% v( a, H5 |5 `5 z) @9 L$ C
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 # Q# ~' I! e+ e, f* Q
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 A0 S& q. q( r
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
' D- o8 u0 c2 E* Q,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 + X+ f) a# s" w) K& {- T4 B% |3 `6 u
文件转换为GB码文件,即得到码表文件。 ! K* K$ e6 L: a0 c
下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table.
& h7 M4 g1 I5 k& ZTXT”。 9 z/ h8 }4 q" T, I5 w+ u t
//TURBO C++ 3.0
. w4 v/ _( G) F) p e#include <Stdio.h> 1 R& s! V9 K9 t& j y: a
#include <stdlib.h>
/ s6 F& m* w* cvoid main(){
& ~( j/ c* `7 h, I c& k+ X5 n+ {FILE * codefile;
6 u" x% x, l0 _# P! sint i,j,k;
" H0 t3 G/ a8 P! c% c3 x" D8 i+ _codefile=fopen("table.txt","w+b"); : b) A) h7 u, r m$ z
for (i=0xa1;i<=0xfe;I++){
" E3 i2 Z$ O5 ]1 t( K% k& j; _% Afor(j=0x00;j<=0xff;j++){
. T/ U5 |/ Y- h. L& Ufwrite(& i,1,1,codefile);
' G; ?2 e( } u" M" d/ ~# J- ~fwrite(& j,1,1,codefile);}
+ {5 N; D# j* o- o* j8 C5 w}
& X3 Y7 O3 p+ Ufclose(codefile);
) G- ?, m; e4 O. m9 z/ ?return;
/ O4 m: d2 m. L}
, a- S3 z0 g0 V* N: Q 运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码,
- ]% L# l9 P% }% m" m即获得码表文件。 & C$ {! b% t U' o: E9 _" H
第二步 转换
0 @0 B3 u# p0 e6 ]9 A" w+ q 下面的源程序,将BIG5码文件转换为GB码文件。 / o: Z! L r" V, k1 }+ N
//TURBO C++3.0 - F" T7 O0 W* U! i; a2 M) d0 J) O
#include <stdio.h> " X: K8 z4 J# X4 f* D
#include <stdlib.h>
& A( U( V, w uvoid main(){ 3 {0 ?6 m7 o. h8 z- Y7 d
int que, wei; 7 M. c5 ^0 T4 r. b' I
FILE * sourcefile; / s% P% \5 m# n2 ]
FILE * tabfile;
+ q$ E! s5 ~# MFILE * destfile; ( f1 t7 u! l0 {- Q: Q, F
sourcefile = fopen("big.txt', "r+b"); 7 T% P- e# N- E- U# ^5 i" M
//BIG5 码文件 9 n( \5 ~& `1 P; ?9 K# r( ]6 S
tabfile = fopen("table.txt", 'r+b"); . m6 w$ x3 J7 g2 u# M+ r
//码表文件 : [" R4 ?. j2 l
destfile = fopen("gb.txt","w+b"); $ l( Z. ?5 [, r6 n* f- i. J% F
//转换生成的GB码文件
. o4 Z6 ~6 V- l4 C4 ywhile (!feof(sourcefile)){ C& b% E: \$ i0 G: H$ m
fread(& que,1,1,sourcefile);
+ Q- p% M; A& p$ t9 Dif (feof(sourcefile)){ ) P/ @' q1 `6 }6 K
break; } c3 ^8 k& s% K! D5 }2 k0 F
if (que> =0xa1 && que <=0xfe) & W3 C" k% C5 N$ Z7 P
//叛断是否汉字(BIG5编码)
& }( U9 k" f2 i* y{fread(& wei,1,1,sourcefile); 9 G% `( j; E* B, m& T
if (wei<0xa1) wei = wei - 0x40; 1 d. d; q+ h1 _8 ~1 t
if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1;
4 Y7 Z: ~0 U, n7 w5 yfseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 )
* h% V2 ?" \ V$ {5 N g E4 m) K3 j + wei), SEEK_SET);
" v. ]* m) h7 `1 S7 m$ G8 \( Afread(& que,1,1,tabfile); % b, Y/ x- V" c" x8 c
fread(& wei,1,1,tabfile); - Z; @8 w' b# Z6 J' j Q, a+ T
fwrite(& que,1,1,destfile); - Z1 L) k% s1 J: C% B. `: w+ [4 w
fwrite(& wei,1,1,destfile);
- v: P. ^; N) C3 F t2 d}
, R8 \3 M& n3 O! T/ P0 Qelse 5 \0 w; Y9 R H: `+ e: F& l* F% P
fwrite(& que,1,1,destfile); //处理英文
$ D3 M. w) ]- `} ' n& U3 v( v& |3 Q: \) s F3 P
fclose(sourcefile);
; {& G* [1 W2 N! ffclose(tabfile); # S7 N+ {# M$ M/ v
fclose(destfile); ( q/ e6 l+ ^/ }5 j
return; * {2 `0 G# b, u$ `0 l1 a8 g
} 7 H2 D* [1 W; K F$ v4 q
以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用
4 j7 l7 I- D. N& Y8 P7 H* h同样的方法,我们也可以将GB码转换为BIG5码。 |