|
BIG5到GB的转换技术
+ K4 p# J) x d, o ( C) c7 c o8 b: V# E
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
2 i6 S+ W4 {$ K4 H0 s ~9 i( E0 [来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置
; c# J T# x: m9 z; r" C$ g。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 " o4 Z3 U& O. g" f6 W0 f* {
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个
/ O( ^) c5 [! s9 B! W汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。 : j9 E) l& d; C* i8 @6 X
汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
( h2 n! e+ q( K& A C2 V7 q码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码
: S( n s4 O' z* O$ i0 ^0 n(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
& C' Y; [" X- F, ^BIG5编码对应GB编码的码表文件。 3 C; p. e1 A$ {" c
第一步 制作码表文件 & y9 o- o- b3 i5 g
BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 , {/ }" `) }4 r
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
$ ^. O! d+ K: H# R( P157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 ! D! s8 h' E, Z+ [, B6 V
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的
1 k4 u/ H$ i! N0 x范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 ; U; c+ v/ t) ~" _
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 * \1 d- j+ p8 r+ A4 ~* `
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后 $ a0 j& D6 k4 |( b6 I
,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将
- P( w4 \7 L7 Z& T+ H6 h$ ?* B文件转换为GB码文件,即得到码表文件。
5 g8 N, ?( _% \" H( W 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table.
- h& d$ J2 l% P9 t9 Q, V" DTXT”。 9 \7 E; ^5 X5 ]* \4 \9 }+ s) O* `
//TURBO C++ 3.0
]$ ?1 E; {# }; [9 o4 c V4 N#include <Stdio.h> $ g8 J! V2 Z1 i
#include <stdlib.h>
7 H1 N4 w0 Q1 j- r3 X6 _4 A" L. Y) ~void main(){ 4 P" v) [. g! V+ c$ d
FILE * codefile;
& S1 Z) d7 S* G7 Q' _5 bint i,j,k; ( d& E7 Q$ i6 h0 D
codefile=fopen("table.txt","w+b");
8 b: q% Z* M3 D, bfor (i=0xa1;i<=0xfe;I++){
A9 l M& Z, u7 h. P' ?' R4 afor(j=0x00;j<=0xff;j++){
/ N2 d/ t& F' z, b B+ Pfwrite(& i,1,1,codefile); ' i# @+ F+ f0 |( Q
fwrite(& j,1,1,codefile);} 0 J9 I2 n# g0 m. T1 @
} 3 r+ |( q/ C8 Y. ^3 B
fclose(codefile); 8 ?+ v) @: G$ z! ]$ k0 O5 o
return;
7 \5 j! O" I# G- z* i3 b5 h} + M/ B, a0 e1 y2 f$ a
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, / h- h: W8 M) a' K+ l7 k
即获得码表文件。 / |0 I8 J7 |; b( j0 p1 I
第二步 转换
4 B* V$ [0 u4 Z- s) G 下面的源程序,将BIG5码文件转换为GB码文件。 # {0 q* {: `( C% q! {% d
//TURBO C++3.0 : g( X% Y% ]" w" a; c0 E% i( }
#include <stdio.h> ) ~8 u( f6 g% w" J( O/ y! }
#include <stdlib.h>
! n6 g! p# R( h5 m8 s, o- ]void main(){ 7 ], w& C" w! P$ a' D
int que, wei;
+ M+ X, e7 z X8 \. ]4 d ]. JFILE * sourcefile; : U5 l* q- x' r) _0 B0 L* w: B
FILE * tabfile;
) G. {1 R7 Q4 f' m3 \FILE * destfile; ( e! }- f( J0 m4 s: e/ T
sourcefile = fopen("big.txt', "r+b"); 9 h& b- S% n% b/ | z, W' r& K# k/ P
//BIG5 码文件 8 A1 o/ u& ~5 \& e' f5 T8 v
tabfile = fopen("table.txt", 'r+b"); * ~$ C8 q. l- B) S+ B
//码表文件
/ X9 k8 c+ E4 ~% t; H7 {destfile = fopen("gb.txt","w+b");
+ j# _5 O4 W, }* {, g& P' B# C//转换生成的GB码文件
5 N4 h: a% D; e( B8 v/ t# n) Kwhile (!feof(sourcefile)){ + O. u( c M- @. O/ A+ H
fread(& que,1,1,sourcefile); + `. J7 n5 R: z1 r: G) O4 o' S' k
if (feof(sourcefile)){
. Q0 g# _+ k+ nbreak; }
4 d, ^% i1 \( `" rif (que> =0xa1 && que <=0xfe)
1 S3 ?8 [' O$ P4 z//叛断是否汉字(BIG5编码) 4 y) T8 Q2 x3 R8 ^3 ^( N$ R" [
{fread(& wei,1,1,sourcefile);
) J9 Y: m |0 E2 O& n. Iif (wei<0xa1) wei = wei - 0x40;
3 B3 }' y$ h6 \2 i; c( h" Iif (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1; ; j! k- a( o7 {$ m( m
fseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) 3 Z# z" u8 g' t$ P" o9 v+ ^7 Q
+ wei), SEEK_SET);
2 ]0 g# [1 x$ T' j. h9 Wfread(& que,1,1,tabfile); " f. `! `- u7 g! }
fread(& wei,1,1,tabfile);
" P. ~3 X0 s( u, P! Y9 Tfwrite(& que,1,1,destfile); . }8 t) r9 M5 K8 L/ u
fwrite(& wei,1,1,destfile);
% D% W7 p, R! `. s: I: t} ) t7 g+ @5 O3 t
else 7 N* f% f1 y1 b' }- T& V
fwrite(& que,1,1,destfile); //处理英文
6 a$ U& I) |* a( q}
6 V+ k. D. m7 P! M8 n+ W8 zfclose(sourcefile);
* i, b9 S1 b! a& @7 S" K3 tfclose(tabfile); 3 T4 T' P1 H8 ]9 y1 m9 z5 }
fclose(destfile); - _4 G5 x* o3 k% U* Z
return;
, B |/ v: m5 H& \}
3 c2 a8 H5 ~. m. Q6 H 以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用 , e. z% N3 n1 F: l
同样的方法,我们也可以将GB码转换为BIG5码。 |