|
BIG5到GB的转换技术
( e6 ]7 p. U& B) p2 w% p " C# A3 f" C6 x' b! d* _/ p% y
中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
9 d" H) d' f( o: R0 f来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置
: }3 L! q- ]7 s* r。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就
" {; e2 P; C, ^7 Q( x可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个
' a( G. C; S* L0 l汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。 I- ~0 h) n3 p
汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
9 y& r" [6 V" m4 o, W8 ~/ E# ?; V码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 y# a* u6 {) B k
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个
: w; L ~4 {$ \, y$ p: YBIG5编码对应GB编码的码表文件。
7 i0 N" O; a. O( z% A第一步 制作码表文件 . D/ e6 ^+ ?/ o& l" Q
BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从 # M6 u. k7 R$ T( f8 Z1 P. \4 x
0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
7 Q" q+ [' _+ y+ I157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些
) D8 O7 H o5 E8 x( V+ Y汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的
1 y7 A/ r& q1 G0 L范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用
7 {& R" S! j- Q3 g字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 , E3 S/ n; n2 K- M7 e% _
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
7 G7 Q; j7 J1 P$ \,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将
' D0 M+ f% u' o1 \/ l8 `文件转换为GB码文件,即得到码表文件。
1 i) j3 U" y# W- K/ z5 a 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table.
: M( g% H8 e/ X3 R5 \TXT”。 % B8 [0 e7 O5 a: `
//TURBO C++ 3.0
3 Z. \6 }, ]4 ]% t5 S0 l#include <Stdio.h>
1 {/ p1 {# ^$ e k: J9 L#include <stdlib.h> 4 Y' f4 Z+ a/ f. l+ X
void main(){ 4 J8 ]0 W. @& g9 E; Z8 D% d/ R
FILE * codefile; 4 m* k4 |0 E' z% h, ^$ \
int i,j,k;
- w5 X! p& L8 Qcodefile=fopen("table.txt","w+b");
, ?! F% B3 S5 K+ Bfor (i=0xa1;i<=0xfe;I++){
& f p; E+ ?/ \$ ?, y$ `( Afor(j=0x00;j<=0xff;j++){ # O) C$ [. }/ r( l) R+ c9 i$ o
fwrite(& i,1,1,codefile); ( [: u! q$ i1 \1 ^' ^+ L4 v! E
fwrite(& j,1,1,codefile);}
! D9 _4 E/ I# r$ D$ Z}
$ |, n8 o: Y& W+ |5 {: p( c) Mfclose(codefile); $ ?7 V5 Y y$ j
return;
, ?, z0 g6 T* V, q} . H0 k' i* s8 ]' U, L, j
运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, 5 {4 l5 A9 Z% \* x# ?$ z+ Q1 h! G9 k- r1 i
即获得码表文件。 , \% U' {5 F3 P% l2 H9 r; O; `
第二步 转换 6 X. r6 ]) _; P5 N/ Y% L0 P
下面的源程序,将BIG5码文件转换为GB码文件。 4 p5 Y' d, [- b9 }
//TURBO C++3.0
, ~$ l/ D }( Z, F& J! }7 J#include <stdio.h>
, v% O! u8 Q3 J, m#include <stdlib.h> |" h+ o- j: J* {
void main(){ 5 ?' w/ A% \/ g7 Z0 D6 k( C1 e
int que, wei; ) M& P" h7 m- A( Q
FILE * sourcefile;
: M- ~2 ]: ?6 hFILE * tabfile;
! i0 y6 N" a' v' O* aFILE * destfile;
6 k. G0 H4 C {5 U( w* `9 Rsourcefile = fopen("big.txt', "r+b");
3 y# t' k3 W9 H) V* K: n: }9 U//BIG5 码文件 + a9 _9 ], r+ {1 L7 S4 Z/ \( y" B
tabfile = fopen("table.txt", 'r+b");
$ `0 [4 h- X0 L//码表文件
) R9 P5 U! }' ~: Sdestfile = fopen("gb.txt","w+b");
0 v$ j+ ~( M- b4 V G//转换生成的GB码文件
3 h1 A8 R. O7 b: O# P! Vwhile (!feof(sourcefile)){ [" |+ A8 ~9 l# @
fread(& que,1,1,sourcefile); % V3 v5 [# w1 f% [* _
if (feof(sourcefile)){
/ a( K% N) ?8 o* y9 abreak; } . z! u% }3 f5 H& H; y
if (que> =0xa1 && que <=0xfe) 8 L- p! k% n3 T, g! r' D
//叛断是否汉字(BIG5编码)
! A5 _+ g, @- ` Q8 F, T6 Y{fread(& wei,1,1,sourcefile);
* E; e- P- ~) }* Y. Iif (wei<0xa1) wei = wei - 0x40;
/ l$ N, u5 B8 V# `9 V! v( c( Zif (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1;
( B* D: w; A" [, {: v& Lfseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 )
, r( y& ~: v7 P( H + wei), SEEK_SET); ) C1 E1 {* W1 X$ F' W; H, x7 m
fread(& que,1,1,tabfile); 9 k$ r% } H# }- P L& t
fread(& wei,1,1,tabfile);
- W1 {1 K" A) Q! I; Y- q( X! rfwrite(& que,1,1,destfile);
: n2 I/ k. }6 i6 N; T1 W5 Pfwrite(& wei,1,1,destfile);
/ C0 ~2 o- g6 M}
# n) x$ v, O! |; Aelse " M K2 p; O( u0 _) L, T9 T
fwrite(& que,1,1,destfile); //处理英文
+ }8 K2 U! c6 K! \# F+ C}
+ h- b$ ]6 [9 c7 X4 [( r) Ofclose(sourcefile);
1 l; r* O+ W/ [; _1 P3 W8 bfclose(tabfile); - f7 o2 ]" n2 A7 B6 c! t
fclose(destfile);
( b/ s! |) O- yreturn;
$ L V* T5 N! o \0 @} ( C7 p, e1 o( P4 E* u( h- J" v
以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用
6 d( g- e Z {6 B同样的方法,我们也可以将GB码转换为BIG5码。 |