EBCDIC和GBK/GBK2312的转换AS/400中的实现
AS/400采用EBCDIC编码保存在QSYS.LIB中的所有中文字符,而在pc端winows 95,
windows NT采用GBK内码保 存中文字符,两者之间在进行中文数据传输的时候,会遇到EBCDIC和GBK的相互转换。所以,掌握EBCDIC和GBK 的转换码表对于程序员非常重要。
1 收集GBK字符文件
首先必须根据GBK的编码原则得到GBK的汉字库。GBK的编码区间为0X8140到0XFEFE。整个码表分为 5个区间,称为GBK1(A1A1 A9FE)、GBK2(B0A1 F7EE)、GBK3(8140 A0FE)、GBK4(AA40 FEA0)、GBK5(A840 A9A0).其中GBK1包括符号717个,GBK2包括GB2312汉字6763个,GBK3包括GB13000.1中的汉字6080个,GBK4包括增补的汉字8160个,GBK5包括扩充汉字符号166个。
程序1:
/* file1.c */
#include<stdio.h>
void main(void)
{
FILE *fp;
char ch[4],file[10],enter[2],hi,lo;
long int i;
enter[0]=0x0d;
enter[1]=0x0a;
printf("please input the file name:\n"
scanf("%s",file);
if((fp=fopen(file,"wb")==NULL)
{
printf("cannot open %s\n",file);
exit(0);
}
hi=0xa7;
lo=0x40;
for(i=0;i<2*191;i++)
{
ch[0]=0x22;
if(i%191==0)
hi=hi+1;
ch[1]=hi;
ch[2]=(lo+i%191);
ch[3]=0x22;
fwrite(ch,sizeof(char),4,fp);
fwrite(enter,sizeof(char),2,fp);
}
}
程序说明:
(1).OX22是'"'(双引号)的16进制代码,0X0D 0X0A是换行符号的16进制代码,在每一个字符的两旁增加双引号和缓行符号是为了满足CPYFRMIMPF对Import file的格式要求而特别增加的。
(2).结果文件假设命名为GBK.TXT,文件样本见附件。
程序2:得到没有" "和0X0D 0X0A的汉字字库文件
#include<stdio.h>
void main(void)
{
FILE *fp;
char ch[2],file[10],hi,lo;
long int i;
printf("please input the file name:\n"
scanf("%s",file);
if((fp=fopen(file,"wb")==NULL)
{
printf("cannot open %s\n",file);
exit(0);
}
hi=0x80;
lo=0x40;
for(i=0;i<126*191;i++)
{
if(i%191==0)
hi=hi+1;
ch[0]=hi;
ch[1]=(lo+i%191);
fwrite(ch,sizeof(char),2,fp);
}
fclose(fp);
}
[注]:
假设结果文件命名为GBK_01.TXT
2.利用FTP把GBK.TXT上传到AS400的IFS的目录下,例如/home目录,注意ftp在传输双字节的时候需要制定AS400端CCSID的值。如果只传输GB2312汉字,指定CCSID=1381;如果传输GBK汉字,指定CCSID=1386.
[注]:
如果传输正确,使用DSPF或EDTF可以看到正确的中文字符。
3.利用STRSQL交互式SQL生成接受GBK汉字的数据库文件
CREATE TABLE GBK(COL CHAR(4) CCSID 138
4.利用CPYFRMIMPF把流文件数据导入GBK数据库文件
CPYFRMIMPF FROMSTMF('/home/gbk.txt')
TOFILE(GBK/QGPL)
RCDDLM(*LF)
5. 利用FTP的BIN方式,把GBK的文件下传到PC的得到GBK.MBR,从PC端用NOTEPAD观察可以看到文件有许多乱码,这是因为GBK.MBR 使用的是EBCDIC,许多编码在PC上无法识别,而且可以发现每个汉字EBCDIC代码的两旁有0E..0F的标识符,这样观察起来很不方便,使用下面的程序把0E..0F剔除。
程序3: 剔除.mbr中的0E..0F字符
#include<stdio.h>
void main(void)
{
FILE *fp1,*fp2;
char f1[10],f2[10],ch[4];
scanf("%s",f1);
scanf("%s",f2);
if((fp1=fopen(f1,"rb")==NULL)
{
printf("error open input file %s\n",f1);
exit(0);
}
if((fp2=fopen(f2,"wb")==NULL)
{
printf("error open output file %s\n",f2);
exit(0);
}
while(!feof(fp1))
{
fread(ch,4,1,fp1);
if((ch[0]==0x0E)&&(ch[3]==0x0F))
{
fwrite(&ch[1],1,1,fp2);
fwrite(&ch[2],1,1,fp2);
}
}
fclose(fp1);
fclose(fp2);
}
[注]:
假设得到的没有0E..0F标识的文件名称为GBK_01.MBR
6.利用GBK_O1.TXT,GBK_01.MBR得到EBCDIC< >GBK的转换码表文件
程序: 得到最终转换文件
#include<stdio.h>
void main(void)
{
int i;
FILE *in,*out,*gb;
unsigned char ch[2],ch2[2];
char str[40],str2[40];
char enter[2],space=' ';
enter[0]=0x0d;
enter[1]=0x0a;
if((in=fopen("gbk_01.mbr","rb")==NULL)
{
printf("cannot open file\n"
exit(0);
}
if((out=fopen("gbk_cvt.txt","wb")==NULL)
{
printf("cannot open outfile\n"
exit(0);
}
if((gb=fopen("gbk_01.txt","rb"))==NULL)
{
printf("cannot open hzgb.txt\n");
exit(0);
}
while(!feof(in))
{
fread(ch,2,1,in);
fread(ch2,2,1,gb);
sprintf(str,"%02x%02x",ch[0],ch[1]);
sprintf(str2,"%02x%02x",ch2[0],ch2[1]);
fwrite(ch2,2,1,out);
fwrite(&space,1,1,out);
fwrite(str,5,1,out);
fwrite(str2,5,1,out);
fwrite(enter,2,1,out);
}
fclose(in);
fclose(out);
fclose(gb);
}
[注]:
假设最终得到的转换文件为GBK_CVT.TXT
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论