|
BIG5到GB的转换技术 & v$ E7 c# D0 g% J# e
& S% L. f/ e6 |. n& f中文因为数量太多,所以与英文用ASCII码一个字节表示不同,它使用两个字节
1 ^. l B: G/ `5 T3 c来表示。通过计算这两个字节,我们可以得到其表示的汉字在中文字库中的位置 $ m! [1 K3 o- Y: c
。读取该位置的若干字节,以获得表示这个汉字的点阵信息。有了这些信息,就 ' C5 m4 h* R' [# P- G
可以分别在DOS或WINDOWS中显示该汉字。事实上,在文本文件中保存的就是每个 & K! w( f$ s7 r+ S D
汉字对应的两个字节编码,而显示问题由中文操作系统自动解决。
( e' |. K- _7 p) G% e! p 汉字编码并不统一,我们使用的是GB码,而台湾地区使用的是BIG5码。BIG5
2 v& J4 w3 @1 F, Y& D7 Q( m! C码文件中保存的是汉字相应的BIG5编码,GB码文件中保存的是汉字相应的GB编码 ( \, u0 T1 }3 j5 d. P2 _# K. h
(这也就是“乱码现象”的来由)。所以转换工作的关键是有一个记录每个 1 s S3 ]- b a/ u/ @
BIG5编码对应GB编码的码表文件。
# J- C; k$ k. d# O' Q$ |第一步 制作码表文件
- i( {7 F: ~) N7 @( Q1 v BIG5码编码规则是这样的:每个汉字由两个字节构成,第一个字节的范围从
( e8 J! J U" r3 O0X81-0XFE,共126种。第二个字节的范围分别为0X40-0X7E,0XA1-0XFE,共
' v4 M6 W+ P3 N' b6 p0 X) v157种。也就是说,利用这两个字节共可定义出 126 * 157=19782种汉字。这些
! a/ }2 Z7 ]6 {7 K+ Z. u! w汉字的一部分是我们常用到的,如一、丁,这些字我们称为常用字,其BIG5码的 . c3 G: G- `& e2 Y) Y
范围为0XA440-0XC671,共5401个。较不常用的字,如滥、调,我们称为次常用 % j s* }# j3 u6 `/ E
字,范围为 0XC940-0XF9FE,共7652个,剩下的便是一些特殊字符。 . [' t2 R4 E: m. t6 B4 m
制作码表文件的原理是这样的:首先将所有的BIG5编码写入一个文件,然后
# f/ S- e3 u+ _3 ?8 i% h,使用具有BIG5码到GB码转换功能的软件,如地球村、东方快车、四通利方,将 / ^9 ?" w2 s0 l! i4 c
文件转换为GB码文件,即得到码表文件。
8 a, p$ Q" _" K: j2 s8 o 下面的源程序将所有可能的BIG5编码(0XA100-0XFEFF)写入文件“Table. & d7 C Z& h2 V, D. T! ^7 a1 L
TXT”。 1 E& w! z/ W# z; i1 q- j( {
//TURBO C++ 3.0
6 d! p6 M, [$ X+ ?; |/ B; W#include <Stdio.h>
% S8 f8 c1 J+ h4 W3 T6 K8 o- S#include <stdlib.h> " \/ l3 u! L3 `
void main(){ , a ^4 t, \" Q( [; Q' v
FILE * codefile;
% o; e8 I5 i; I- Sint i,j,k; ! v5 N# i# k( V
codefile=fopen("table.txt","w+b");
: g/ g: V1 y# J( \for (i=0xa1;i<=0xfe;I++){ % u7 Z3 k( l# ], G+ F3 Z8 K
for(j=0x00;j<=0xff;j++){
0 O+ x9 ~; [3 G0 ?( gfwrite(& i,1,1,codefile);
R: z* f! }2 ]) f5 mfwrite(& j,1,1,codefile);} % t! R3 c7 n; d6 b; h" |2 W
} K) E* ~' s2 U$ K( i
fclose(codefile);
0 d Y1 F: ? h# [return; 4 ~. h; R; \0 k- C
}
! W) {/ e9 ]9 E! f5 F) N 运行地球村、东方快车或四通利方,将“Table.txt”从BIG5码转换为GB码, ( F# F! g. s; R! t9 x; y6 H
即获得码表文件。 4 `1 g+ r, P/ C1 S: N
第二步 转换
7 r/ o# c l4 o" T0 h/ A E( Z2 q/ ` 下面的源程序,将BIG5码文件转换为GB码文件。
. p: f5 p1 p& n' x9 h//TURBO C++3.0 1 G( r7 `9 T- o$ h8 [: V
#include <stdio.h>
% f, Q/ T2 K7 P) Q#include <stdlib.h>
I$ f- D( P3 Y9 {void main(){
3 u% K# i4 \/ Q2 \' B4 Mint que, wei; 7 W- x+ \) g5 ?! F1 T( Q4 l
FILE * sourcefile;
H0 C3 L" y/ e' TFILE * tabfile;
+ {) ^5 w3 i8 W& e% f. dFILE * destfile; 6 b+ V! y, z [0 h- x: u3 a& `# `
sourcefile = fopen("big.txt', "r+b"); / e1 I3 V: a' C( I" v F4 k
//BIG5 码文件 . ^0 o( B3 I" G+ {# m; F
tabfile = fopen("table.txt", 'r+b"); $ } M& b/ v' o; a; z* ?# W
//码表文件 1 I- @1 C7 ~- j. k# E) D3 S+ Q* b
destfile = fopen("gb.txt","w+b");
* {3 z7 T) e: P//转换生成的GB码文件
0 l- Y3 x' g. \4 ywhile (!feof(sourcefile)){
. z- R1 F! C9 K( o) \5 Jfread(& que,1,1,sourcefile); ! Y9 q4 n4 r9 ~; j" l+ F* B( s b! C
if (feof(sourcefile)){
& y+ ]( ]; k/ Sbreak; } 3 e! W2 N9 i9 Y9 J% ~+ p
if (que> =0xa1 && que <=0xfe) " `) J* R. m9 H7 P. {; Z9 y
//叛断是否汉字(BIG5编码)
% H, u" s$ z: @' q0 t: c{fread(& wei,1,1,sourcefile);
- x; r7 E% y. l1 q4 y7 rif (wei<0xa1) wei = wei - 0x40; + J( }% J4 g/ U/ @; Q; W
if (wei>=0xa1) wei = wei - 0xa1 + 0x7e - 0x40 + 1; ' I+ I6 s) l m" U
fseek(tabfile, 2 * ((que -0xa1) * (0xfe - 0xa1 + 1 + 0x7e - 0x40 + 1 ) 2 E+ k, }* l1 s4 e4 p# x" N
+ wei), SEEK_SET); 0 I! ^7 `0 P! b# |6 Z
fread(& que,1,1,tabfile);
7 b/ J3 M E, J' A/ u3 `fread(& wei,1,1,tabfile);
/ W- V& Z1 e1 T2 X2 R( Q/ k0 Ffwrite(& que,1,1,destfile);
& {. z# v4 y, U. kfwrite(& wei,1,1,destfile);
$ P+ t: a" {! s( U/ a, M0 M}
% K' f* X" o8 n( Qelse
& ^0 P" O5 U; T0 q1 sfwrite(& que,1,1,destfile); //处理英文 ) h/ Z& a" ^/ S5 o0 ?- c
} / g: y( k5 O5 f4 b( k
fclose(sourcefile); / p& K# x; M: Y" N; ` m
fclose(tabfile);
- J* D. ^9 l! k8 lfclose(destfile); : |0 w4 @5 W0 U7 I J! Y) M, W
return;
# J' \1 j* E8 M7 I L0 K}
+ @5 B4 v2 n1 k- h7 U5 [5 o 以上程序在Win95/97,TC3.0 通过。稍加修改,也可用于VC或VB程序中。用 3 w6 ` X$ l6 s' n# O `8 x4 d" O& L
同样的方法,我们也可以将GB码转换为BIG5码。 |