crshen
中级用户
积分 447
发帖 126
注册 2004-2-10
状态 离线
|
『第
19 楼』:
Quote: | 以下是引用jiaking在2005-1-18 1:36:07的发言:
也给我一份源码吧!谢谢!
这么多人要代码,楼主何不慷慨点,放上来让我们大家学学,一起进步? |
|
这位大侠说得对,可惜你没看看这是什么时候的帖子,当时我发贴后长久没人回应,以为没什么用,竟然把源程序删除了,隔了4个月多,才有人要。
由于后面半年我自己外出学习,一直未能回复大家,现在既然有人要,只好重新做了个提取、显示汉字的程序,附后,
使用说明:
1. 程序本来是tc++编译的,加上wildargs.obj支持可以使用*和?通配符,现改为tc2程序,仍可运行,但不支持通配符;
2. 本程序运行要ucdos下的hzk16支持;
3. 对需要处理的程序进行处理后生成2个文件:Hz.h和Hzlib.c,其实为程序内嵌小汉字库;
4. 把程序相关部分复制到一个程序中,或者利用工程文件也可以,已测试能通过tc2.0编译。
附:hz2c.c 提取汉字程序
#include "graphics.h"
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "string.h"
#define macHzNum 7000
/*可以记录的汉字最多字数*/
#define macMaxLineLength 256
/*源程序中每行的最大长度*/
unsigned int HzSum=0 ;
/*记录小字库数组中的汉字数*/
FILE*fp1 ;
/* C,CPP源程序文件的文件指针 */
FILE*fp2 ;
/* 生成的hz.h文件的文件指针 */
FILE*fp3 ;
/* 生成的hzlib.c文件的文件指针 */
FILE*fHz ;
/* UCDOS的16点阵字库HZK16的文件指针 */
unsigned char Chinese[2];
/*记录一个汉字的内码*/
char HeadFile[]="hz.h" ;
/*生成的.H文件的文件名*/
char CFile[]="hzlib.c" ;
/*生成的.C文件的文件名*/
unsigned int HugeBegin=1800 ;
/*使用Huge编译模式的最少汉字个数*/
unsigned char IsHuge=0 ;
/*是否需要Compact、Large、Huge变异模式的标志*/
struct strHz
{
unsigned char QuHao ;
/*汉字的区号*/
unsigned char WeiHao ;
/*汉字的位号*/
unsigned int RecNum ;
/*汉字在HZK16文件中的记录号*/
unsigned char Chinese[2];
/*记录汉字的内码*/
}
;
/*此结构记录一个汉字的区号,位号和字库中的记录号、内码*/
struct strHz lay[macHzNum];
/*存储结构的数组*/
/*此函数根据输入汉字的区号,位号在小字库数组中查找这个*/
/*汉字是否已经提取进入小字库数组。如果没有,*/
/*则加入小字库数组中。返回值是汉字在HZK16中的记录号*/
int map(unsigned char QuHao,unsigned char WeiHao)
{
int i ;
unsigned int RecNumTemp ;
RecNumTemp=(QuHao-1)*94+(WeiHao-1);
/*得出在HZK16中的记录号*/
for(i=0;i<HzSum;i++)
{
if(lay.RecNum==RecNumTemp)
return lay.RecNum ;
/*在小字库中已有此汉字*/
}
/*在小字库数组中没有此汉字*/
lay[HzSum].QuHao=QuHao ;
lay[HzSum].WeiHao=WeiHao ;
lay[HzSum].RecNum=(lay[HzSum].QuHao-1)*94+(lay[HzSum].WeiHao-1);
memcpy(lay[HzSum].Chinese,Chinese,sizeof(Chinese));
/*记录汉字的内码*/
HzSum++;
return RecNumTemp ;
}
/*本函数负责提取C,CPP源程序中的字符串中使用的汉字*/
void IndexHzStr(char*str)
{
unsigned char QuHao,WeiHao ;
unsigned char ch ;
int page,length ;
int MyLibRec ;
static unsigned char InString=0 ;
/*判断是否在字符串中的标志*/
unsigned char HalfChinese=0 ;
/*判断是否是半个汉字内码的标志*/
while((ch=*str++)!='\0')
{
/*以"为进入和退出字符串的标志*/
if(ch=='\"')InString=!InString ;
if(InString)
{
/*是汉字*/
if(ch>=0xa1)
{
if(HalfChinese==0)
{
QuHao=(ch-160);
HalfChinese=1 ;
Chinese[0]=ch ;
continue ;
}
else
{
WeiHao=(ch-160);
HalfChinese=0 ;
Chinese[1]=ch ;
map(QuHao,WeiHao);
}
}
}
}
}
/*本函数根据统计生成的小字库数组,排序生成.H文件。*/
/*在生成.H文件的时候,生成的.H文件的汉字点阵数组的汉字*/
/*是依据汉字在HZK16中的记录号经过排序的,这样在输出汉字时*/
/*用二分法查找汉字数组,可以大大地提高输出汉字时的速度*/
void WriteToH(void)
{
int i,j,k ;
int Min ;
long offset ;
unsigned char HzDotBuffer[32];
char HeadFileStr1[8][80]=
{
"#if !defined(__HZ_H)",
"#define __HZ_H\n",
"#include \"graphics.h\"\n",
"/* 汉字点阵数据的结构 */",
"struct HzLib\n{",
" unsigned int RecNum; /* 汉字在HZK16中的记录号 */",
" unsigned char DotBuffer[32]; /* 记录汉字的点阵数据 */\n};\n",
"/* 汉字点阵数据结构数组 */",
}
;
/*.H头文件中的数据*/
char HeadFileStr2[1][80]=
{
"/* 汉字字库数组中的汉字的数目 */\n",
}
;
/*.H头文件中的数据*/
char CFileStr1[1][80]=
{
"/* 本C文件包含了所有使用的汉字点阵数据 */\n",
}
;
/*.C文件中的数据*/
char HFuncStr[12][80]=
{
"/*以下是函数原形的定义*/\n",
"/*使用折半查找的方法在汉字点阵数据数组中*/",
"/*查找汉字并返回汉字的点阵数据。如未找到,则报警出错。*/",
"/*返回1,查找成功;返回0,查找失败*/",
"int GetHzDot(unsigned int RecNum,unsigned char *HzDotBuf);\n",
"/* 根据汉字点阵数据数组来输出含有中英文的字符串 */",
"void hzprintf(int x,int y,int maxx,int maxy,",
" int dx,int dy,int Color,char *str);",
"/* x,y代表输出汉字的起始位置;maxx,maxy代表输出汉字的左边界 */",
"/* 和右边界;dx,dy代表输出汉字时的字间距和行间距;Color代表输出 */",
"/* 汉字的颜色;str是输出的字符串数组,可以是中英文混杂的 */\n",
"#endif",
}
;
/*函数原形的定义*/
for(i=0;i<8;i++)
fprintf(fp2,"%s\n",HeadFileStr1);
for(i=0;i<1;i++)
fprintf(fp3,"%s\n",CFileStr1);
fprintf(fp3,"#include \"%s\"\n\n",HeadFile);
/*当使用的汉字超过1800个的时候,数据总量可能超过 64K,*/
/*因此使用 Huge 修饰符。*/
if(HzSum>=HugeBegin)
{
fprintf(fp2,"extern struct HzLib huge ArrayOfHzLib[%d];\n",HzSum);
IsHuge=1 ;
/*需要特别的三种编译模式*/
}
else
fprintf(fp2,"extern struct HzLib ArrayOfHzLib[%d];\n",HzSum);
fprintf(fp3,"%s","/* 汉字点阵数据结构数组 */\n"
if(HzSum>=HugeBegin)
{
fprintf(fp3,"struct HzLib huge ArrayOfHzLib[%d]=\n{\n",HzSum);
IsHuge=1 ;
/*需要特别的三种编译模式*/
}
else
fprintf(fp3,"struct HzLib ArrayOfHzLib[%d]=\n{\n",HzSum);
for(i=0;i<HzSum;i++)
{
/*把汉字点阵数组进行排序输出到.C文件中*/
Min=i ;
for(j=i+1;j<HzSum;j++)
{
if(lay[j].RecNum<lay[Min].RecNum)
Min=j ;
if(Min!=i)
{
struct strHz strTemp ;
int Size=sizeof(strTemp);
memcpy(&strTemp,&lay,Size);
memcpy(&lay,&lay[Min],Size);
memcpy(&lay[Min],&strTemp,Size);
}
}
/*按汉字的记录号从小到大把汉字点阵数组写入.H头文件*/
offset=(long)(lay.RecNum)*32L ;
fseek(fHz,offset,SEEK_SET);
fread(HzDotBuffer,32,1,fHz);
fprintf(fp3," {\n %d, /*- %c%c -*/\n ",
lay.RecNum,lay.Chinese[0],lay.Chinese[1]);
for(k=0;k<16;k++)
{
fprintf(fp3,"%#4X,",HzDotBuffer[k]);
}
fprintf(fp3,"\n "
for(k=16;k<32;k++)
{
fprintf(fp3,"%#4X,",HzDotBuffer[k]);
}
fprintf(fp3,"\n },\n"
if((i%40)==0)putch('.');
}
fprintf(fp2,"\nextern unsigned int HzSum; "
for(i=0;i<1;i++)
fprintf(fp2,"%s\n",HeadFileStr2);
fprintf(fp3,"};\n\nunsigned int HzSum=%u;",HzSum);
fprintf(fp3,"%s"," /* 汉字字库数组中的汉字的数目 */\n"
for(i=0;i<12;i++)
fprintf(fp2,"%s\n",HFuncStr);
}
void main(int argc,char*argv[])
{
int i ;
char str[macMaxLineLength];
unsigned char ch ;
int ArgcNum=1 ;
unsigned char FirstLine ;
/* 判断是否是C程序的第一行 */
if(argc<2)
{
puts("\nUsage: hz2c filename"
exit(1);
}
for(i=0;i<macHzNum;i++)
{
lay.QuHao=-1 ;
lay.WeiHao=-1 ;
lay.RecNum=-1 ;
}
;
/*初始化记录数组*/
printf("\n\nCompile Chinese characters in C or CPP source to .H .C file for C,CPP\n"
fp2=fopen(HeadFile,"wb"
if(fp2==NULL)
{
printf("Error open %s file to creat!\n",HeadFile);
exit(1);
}
fp3=fopen(CFile,"wb"
if(fp3==NULL)
{
printf("Error open %s file to creat!\n",HeadFile);
exit(1);
}
fHz=fopen("hzk16","rb"
if(fHz==NULL)
{
puts("Error in open file hzk16 (UCDOS 3.0 3.1)\n"
exit(1);
}
/*支持通配符*和?,可以一次处理一批C或CPP源程序*/
while((ArgcNum)<argc)
{
fp1=fopen(argv[ArgcNum],"rt"
if(fp1==NULL)
{
puts("Error open .C or .CPP source file to read!\n"
exit(1);
}
FirstLine=1 ;
/* 刚打开文件,是第一行 */
printf("\nNow Compile %s --> %s , %s\n",
argv[ArgcNum],HeadFile,CFile);
printf("Compile pass one!\nCompile"
i=0 ;
while(!feof(fp1))
{
fgets(str,macMaxLineLength-1,fp1);
if(FirstLine)
{
if(strstr(str,HeadFile)==NULL)
/* 在 C程序中尚没有 #include "hz.h" */
{
char FileTempName[]="temp.$$$" ;
char StrBuff[macMaxLineLength];
FILE*fTemp ;
fTemp=fopen(FileTempName,"wt"
if(fTemp==NULL)
{
puts("Error open temp file to write!\n"
exit(1);
}
fprintf(fTemp,"#include \"%s\"\n\n",HeadFile);
fseek(fp1,0L,SEEK_SET);
while(!feof(fp1))
{
fgets(StrBuff,macMaxLineLength-1,fp1);
fputs(StrBuff,fTemp);
}
fclose(fp1);
fclose(fTemp);
remove(argv[ArgcNum]);
rename(FileTempName,argv[ArgcNum]);
fp1=fopen(argv[ArgcNum],"rt"
if(fp1==NULL)
{
puts("Error open .C or .CPP source file to read!\n"
exit(1);
}
}
FirstLine=0 ;
}
IndexHzStr(str);
if((i++%20)==0)putch('.');
}
printf("\nCompile pass two!\nCompile"
WriteToH();
/*生成.H文件*/
puts("\nCompile pass three!"
fcloseall();
ArgcNum++;
}
printf("\nCompile ok!\t Use Chinese characters number: %d\n",HzSum);
/*提示使用特别的三种编译模式*/
if(IsHuge)
{
printf("\n\7\7\7Chinese characters data amount is more than 64K,\n"
printf("use Compact、Large、Huge mode to compile!!\n"
}
}
附:hzprintf.c 汉字英文显示程序
#include "stdio.h"
#include "conio.h"
#include "string.h"
#include "hz.h"
/*使用折半查找的方法在汉字点阵数据数组中*/
/*查找汉字并返回汉字的点阵数据。如未找到,则报警出错。*/
/*返回1,查找成功;返回0,查找失败*/
int GetHzDot(unsigned int RecNum,unsigned char*HzDotBuf)
{
unsigned int Low,High,Mid ;
Low=0 ;
High=HzSum ;
/*折半法查找汉字的点阵数据*/
while(Low<=High)
{
Mid=(Low+High)/2 ;
if(RecNum>ArrayOfHzLib[Mid].RecNum)
Low=Mid+1 ;
if(RecNum<ArrayOfHzLib[Mid].RecNum)
High=Mid-1 ;
if(RecNum==ArrayOfHzLib[Mid].RecNum)
{
memcpy(HzDotBuf,ArrayOfHzLib[Mid].DotBuffer,32);
return 1 ;
/*查找到了汉字*/
}
}
/*查找失败的处理*/
printf("\7\7\7\nNot find Chinese characters,please recompile your source!\n"
getch();
return 0 ;
}
/* 根据汉字点阵数据数组来输出含有中英文的字符串 */
void hzprintf(int x,int y,int maxx,int maxy,
int dx,int dy,int Color,char*str)
/* x,y代表输出汉字的起始位置;maxx,maxy代表输出汉字的左边界 */
/* 和右边界;dx,dy代表输出汉字时的字间距和行间距;Color代表输出 */
/* 汉字的颜色;str是输出的字符串数组,可以是中英文混杂的 */
{
unsigned char ch ;
unsigned char HalfChinese=0 ;
int QuHao,WeiHao ;
int x0=x ;
char Buff[2];
long RecNum ;
unsigned char HzDotBuf[32];
unsigned char i,j,k ;
while((ch=*str++)!=0)
{
/*是汉字*/
if(ch>=0xa1)
{
if(HalfChinese==0)
{
QuHao=(ch-160);
HalfChinese=1 ;
continue ;
}
else
{
unsigned int RecNum ;
WeiHao=(ch-160);
HalfChinese=0 ;
RecNum=(QuHao-1)*94+(WeiHao-1);
GetHzDot(RecNum,HzDotBuf);
/*输出汉字*/
setcolor(Color);
for(i=0;i<16;i++)
for(j=0;j<2;j++)
for(k=0;k<8;k++)
if((HzDotBuf[i*2+j])>>(7-k)&1)
putpixel(x+j*8+k,y+i,Color);
x+=16+dx ;
}
}
/*处理英文字母和控制字符*/
else
{
/*输出可打印的英文字母*/
if(ch>=0x20&&ch<=0x7E)
{
setcolor(Color+1);
/*英文字母换色输出*/
sprintf(Buff,"%c",ch);
outtextxy(x,y+5,Buff);
x+=(8+dx/2);
}
else
{
switch(ch)
{
case 10 :
x=x0 ;
/*LF=\0,换行*/
y=y+16+dy ;
if(y>(maxy-16-dy))
break ;
/*到了边界,退出输出*/
break ;
case 13 :
break ;
/*CR=\n,回车*/
case 9 :
x=x+32+2*dx ;
break ;
/*TAB=\t,制表符*/
default :
break ;
}
}
}
/*中文和西文的共同的处理换行的部分*/
if((x+dx*2)>=maxx)
{
x=x0 ;
y=y+16+dy ;
if(y>(maxy-16-dy))
break ;
/*到了边界,退出输出*/
}
}
}
|
从来不用别人的东西,要用,也先改成自己的再说! |
|