|
BIG5到GB的转换技术
4 f" k9 m5 I4 m. L
) e) H9 i& w4 R. s, |4 H中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节 8 O" v9 Y, J/ l' \3 a8 P
来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置
3 ~, G, }. ^0 |; y; m。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 8 Q% o7 e, Q: w) n) H% Q$ e6 x
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 & q- g5 [% q, h" n4 Z4 o- v
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。 ' E/ V; _, T+ ]2 I$ a4 S
汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
& J, S$ a+ p" ~码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码
; i. P ^ \% q8 R# X* Y3 }(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
% X q6 ]- [& Q! _& x! aBIG5编码对应GB编码的码表文件。
6 g f$ s, a# C第一步 制作码表文件 ' p1 r8 o( @9 h- p e0 l) ^
BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 , S: [/ x/ x2 l8 O
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共 4 N8 m0 w& }/ K) f' H" a$ e& _/ ?# {
157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些 1 G% U( Z# j N, d3 n6 ?
汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 9 E8 S8 t: A; }4 N- f
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用
1 g9 C$ A6 e! C4 @字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。
8 b8 a; E: K! B6 u: v L 制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
V$ R ]/ F: h. U,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 5 p7 @6 Z! w9 P; y, [
文件转换为GB码文件,即得到码表文件。 & r0 l( p2 A ]# W/ `
下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. ! I$ U! q, g% X
TXT”。 6 O6 R) i' u8 J8 q
//TURBO C++ 3.0
) m$ c3 H' Y% i9 ~#include <Stdio.h>
) t9 J) e7 K+ e4 p& b' |0 e* ~#include <stdlib.h>
( [2 K# k7 u- qvoid main(){
. _5 ^, I; F. c# ?- |8 q$ GFILE * codefile;
+ t) {5 R" I; E( A. q. ~int i,j,k; 7 @" [* m# m6 ^7 _/ K5 U. q6 W
codefile=fopen("table.txt","w+b"); . \8 y# j- e- Y; C$ z* Z
for (i=0xa1;i<=0xfe;I++){ % `3 x9 q f5 E5 Y+ X' Z3 @
for(j=0x00;j<=0xff;j++){ 9 ^2 y5 L' N7 e1 Z8 k- X( ~
fwrite(& i,1,1,codefile); 9 Q5 v) b3 v" |9 i6 c
fwrite(& j,1,1,codefile);} 1 O; u" n# L- i( @
} 9 ]/ o/ o+ f5 ^& d( Y2 A
fclose(codefile);
) ~. L% F* |6 ]$ S- L7 ]% K2 [return;
/ Y5 P1 ~$ L; f5 m6 C z; B}
/ W3 r, |5 a9 _) o( n/ [& g 运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, . Q. o# G2 O( G9 Y. \7 B: ?
即获得码表文件。
( k/ g; q$ @1 h- z9 N0 m第二步 转换 ( R, L3 N) ?3 C* w+ Y
下面的源程序,将BIG5码文件转换为GB码文件。 % d+ f9 ^3 a0 i9 r8 b5 v8 L
//TURBO C++3.0 ( h( e E+ O1 K
#include <stdio.h> 9 O4 \: H" |4 B6 I. k0 J
#include <stdlib.h>
7 L! j( o( f& A( ?: K+ Tvoid main(){
8 U1 [7 `8 o% Pint que, wei; ' W) Y% O( `5 }4 g- } A& O; B
FILE * sourcefile; 8 m( B7 N" v% j$ _7 B
FILE * tabfile;
1 \+ Y; X J& F5 d4 q7 m5 k* YFILE * destfile;
: r) V. c+ t4 nsourcefile = fopen("big.txt', "r+b");
8 J* U1 O& m V3 ? _1 ?//BIG5 码文件 " @" A8 y3 }0 p$ y4 I* q
tabfile = fopen("table.txt", 'r+b"); 7 e- v! R" W% _. c2 Z" h
//码表文件
' C4 V& }% O, M# S8 x! u4 idestfile = fopen("gb.txt","w+b");
- A2 h) i3 m: V4 P( c- `4 ^% D//转换生成的GB码文件 1 U6 H7 J7 A* [0 v
while (!feof(sourcefile)){ : {: ~# u: p) C) z, ?/ I& B
fread(& que,1,1,sourcefile); ' v/ K" w) b1 B
if (feof(sourcefile)){ - m- v5 q! Q$ e; `
break; } 6 ?- E7 B) ~" ?7 Q( p
if (que> =0xa1 && que <=0xfe)
% U& O) F! a& j//叛断是否汉字(BIG5编码)
5 o. R% ]1 j# @3 n5 {7 f{fread(& wei,1,1,sourcefile); ! g5 s8 k' [2 b- ?
if (wei<0xa1) wei = wei - 0x40; $ U' w$ d. f' W \7 Y* ?4 H
if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1; % d* w- X6 x9 p2 [
fseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) 4 f8 y, o0 o, j( [' {+ M
+ wei), SEEK_SET); ) v: N6 I! g- K% N
fread(& que,1,1,tabfile);
5 k4 |- K* `2 ^% D' p+ z$ Mfread(& wei,1,1,tabfile); 4 @% L$ c$ `, J9 p- F8 I2 f
fwrite(& que,1,1,destfile); / p0 \ F9 ]9 P# B: M. p
fwrite(& wei,1,1,destfile);
. Q! v9 N$ @( @1 z} , D# X1 |. J( O' r4 n# \- @
else
" F4 y2 E+ ~; g6 Z7 X/ e- Mfwrite(& que,1,1,destfile); //处理英文
( ?3 b2 e; c* |; S* q9 w} % Y, M2 u% M' G6 d; x- W
fclose(sourcefile);
* A" v8 x/ v0 Z- J& A% m; G1 S, D' Hfclose(tabfile); * t6 m) T0 U4 M- a k' g8 T9 O
fclose(destfile);
1 o A1 W! ]3 K+ L9 Yreturn;
+ b4 \+ U9 e$ Z$ l+ M! u0 P( p9 e( S" a}
8 H: N5 _) s- t, S% t. p% A. z7 ]. Y 以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用
9 }# \2 M: u" p: w3 ]: C同样的方法,我们也可以将GB码转换为BIG5码。 |