⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.cpp

📁 在 BC++ 编译,原代码字模提取程序,可以使用在单片机和液晶自己编程等等.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		  也会提供提取字模的工具.出于商业目的,这些厂家和个人不会给
		  用户提供源代码,用户只能使用而不能学习和修改源码,会感到有些
		  遗憾.
		2.初学者因为好奇,想多了解一点这方面的知识,而教科书里面说的不是
		  很详细(这些雕虫小技,谁写啊),这个程序会满足你对点阵字库方面的
		  好奇心和求知的愿望。
		3.大学里很多学生对c语言不感兴趣,原因大都是:a.教科书太死板b.
		  教师照本宣科.c.大家理论学的多,实践太少.d.不知道究竟用c语言来
		  干什么.其中最后一条是最多的,况且我们从小到大的考试制度,对于
		  科教兴国产生了越来越大的制约,学习的目的渐渐的演变成位考试而
		  学习,这正是教育的悲哀,也是我的悲哀(我大学c语言考试不及格,
		  终生的遗憾啊).这里发点牢骚了.分析这个程序可以帮助你温习你
		  本来已掌握的c语言知识,我用了很多没用的句子,大家可以分析一下,
		  哪些是不必要的,本程序包括了那些方面的知识,为什么会这样. 这正
		  是我的最大的初衷.
		4.本程序在Borland C++ 3.0里编译,C++Buile或Vc++里字长不一样
		  可能需要修改,我没试过.
		5.我这个人很好相处的,欢迎大家和我交朋友.
--------------------------------------------------------------------
*/



void hanzi_view();

void jmain()  // access command-line arguments
{
int argc;
char i;
char*  argv[20];
	FILE *fp1,*fp2;
	union word0
	{
		unsigned long int ll;
		struct bytes0
		{
			unsigned char a;
			unsigned char b;
			unsigned char c;
			unsigned char d;
		}st0;
	}un0;
	union word
	{
		unsigned int ab;
		struct bytes
		{
			unsigned char a;
			unsigned char b;
		}st;
	}un;
	unsigned  char  ch;
	unsigned  int  m;
	//start
	clrscr();
	//--------------------------------------------------------------------------
	//可以通过对argv[1],argv[2]赋值,指出读取的源文件的名称、创建的目标文件的名称
	//argv[1]="FILE1.TXT";//source file
	//argv[2]="FILE12.TXT";//create new file
	//--------------------------------------------------------------------------
/*	if (argc!=3)      						// test number of arguments
	{
        								//命令行参数包括少于3个
		Form1->Memo1->Text="The paramers is < 3 \n"+char(13)+char(10);
		Form1->Memo1->Text=Form1->Memo1->Text+"USAGE: HZK12.EXE FILE1.TXT FILE12.TXT) \n"+char(13)+char(10);
		Form1->Memo1->Text=Form1->Memo1->Text+ "Use FILE1.TXT and FILE12.TXT{y/n}? \n"+char(13)+char(10);
		ch=getch();
		if(ch=='y'||ch=='Y')
		{
			argv[1]="FILE1.TXT";				//source file
			argv[2]="FILE12.TXT";				//create new file
		}
		else
			return;
	}
 */
       			argv[1]="FILE1.TXT";				//source file
			argv[2]="FILE12.TXT";				//create new file
	if((fp1=fopen(argv[1],"rb"))==NULL)
	{
		cout<<"Read FILE1.TXT error !\n";			//FILE1.TXT文件不存在或读取文件错误
		cout<<"Press any key to exit!";
		getch();
		return;
	}
	if((fp2=fopen(argv[2],"rb"))==NULL)				//FILE12.TXT不存在则创建新文件FILE12.TXT
	{
		if((fp2=fopen(argv[2],"wb"))==NULL)			//建立新文件错误
		{
			cout<<"Creat FILE12.TXT error!\n";
			cout<<"Press any key to exit!";
			getch();
			return;
		}
	}
	else
	{
		cout<<"The FILE12.TXT already exist!\n";
		cout<<"Do you want to delete the target file(y/n)?"<<endl;
		ch=getch();
		if(ch=='y'||ch=='Y')
		{
			if((fp2=fopen(argv[2],"wb"))==NULL)
			{
				cout<<"The FILE12.TXT open error!\n";
				cout<<"Press any key to exit!";
				getch();
				return;
			}
		}
		else
		{
			cout<<"Please rename FILE12.TXT !\n";
			cout<<"Press any key to exit!\n";
			getch();
			return;
		}
	}
	clrscr();
//---------------------------------------------------------------------
	cout<<"需要C51 or ASM 格式?\nPlease input 'c' or 'a' \n";
	ch=getch();
	clrscr();
/*	if(ch=='c'||ch=='C')
		cout<<"the data is C51\n";
	else
		cout<<"the data is ASM\n";
*/
	if(k1!=1)
		cout<<"the data is C51\n";
	else
		cout<<"the data is ASM\n";
//=================================================================================
	//写入汉字内码表
	un.st.a=fgetc(fp1);
	fputs("//说明:从 FILE1.TXT 获取汉字内码(任意自造汉字库),从UCDOS文件 HZK12 获取汉字对应点阵",fp2);
	fprintf(fp2,"%c%c",0x0d,0x0a);
//	if(ch=='c'||ch=='C')
     	if(k1!=1)   						//写入C51格式的汉字内码表
	{
		fprintf(fp2,"//汉字内码表:");
		fprintf(fp2,"%c%c",0x0d,0x0a);
		fprintf(fp2,"uchar code hznm [ ][ 2] = {");
		fprintf(fp2,"%c%c",0x0d,0x0a);
		int i=0;
		int j=0;
		for(;!feof(fp1);i++)
		{
			if(!(i%120))
			{
			 fprintf(fp2,"\"");
			 j++;
			}
			fputc(un.st.a,fp2);
			un.st.a=fgetc(fp1);
			if((i%120)==119)
			{
			 fprintf(fp2,"\"%c%c",0x0d,0x0a);
			}
		}
		fprintf(fp2,"\"};");
		fprintf(fp2,"%c%c",0x0d,0x0a);
		if(!(i%120))
		{
		   fprintf(fp2,"//每行60个汉字,共%d行  ",j,(i%120)/2);
		   fprintf(fp2,"总计%d*%d=%d个汉字 测试累加值为 %d",j,60,(j*60),i/2);
		}
		else
		{
		  fprintf(fp2,"//最后一行除外每行60个汉字,共%d行,最后一行%d个汉字 ",j,(i%120)/2);
		  fprintf(fp2,"总计(%d*%d)+%d=%d个汉字 测试累加值为 %d",j-1,60,(i%120)/2,((j-1)*60)+(i%120)/2,i/2);
		}
		fprintf(fp2,"%c%c",0x0d,0x0a);
	}
	else								//写入汇编语言格式的汉字内码
	{
		fprintf(fp2,";汉字内码表,每行最多8个汉字:");
		fprintf(fp2,"%c%c",0x0d,0x0a);
		fprintf(fp2,"hznm_addr:");
		unsigned int i=0;//总共多少字节汉字
		unsigned int j=0;//第几行
		int  t;//统计最后一行汉字个数
		do
		{
			if(!(i%16))
			{
				t=0;
				fprintf(fp2,"%c%cDB 0%0.2XH",0x0d,0x0a,un.st.a);
				j++;
			}
			else if((i%16)==15)
			{
				fprintf(fp2,"0%0.2XH;",un.st.a);
				fseek(fp1,-16L,1);			//文件指针往前移动16字节
				for(int k=0;k<16;k++)
					fputc(fgetc(fp1),fp2);		//把刚才写入的8个汉字注释出来
				un.st.a=fgetc(fp1);
				i++;
				t++;
				if(feof(fp1))
					break;
				else
					continue;
			}
			else
			{
			 fprintf(fp2,"0%0.2XH",un.st.a);
			}
			un.st.a=fgetc(fp1);
			i++;
			t++;
			if(!feof(fp1))
			{
				fprintf(fp2,",");
			}
			if(feof(fp1))
			{
				long ll0=0;
				ll0=t;
				fprintf(fp2,";");
				fseek(fp1,-ll0,1);
				for(int k=0;k<t;k++)
					fputc(fgetc(fp1),fp2);		//把最后一行汉字注释出来
				break;
			}
		}while(1);

		fprintf(fp2,"%c%c",0x0d,0x0a);
		if(!(i%16))
		{
		 fprintf(fp2,"//共%d行,每行8个汉字 ",j);
		 fprintf(fp2,"总计(%d*%d)=%d个汉字 测试累加值为 %d",j,8,(j*8),i/2);
		}
		else
		{		
		 fprintf(fp2,"//共%d行,最后一行除外每行8个汉字,最后一行%d个汉字 ",j,(i%16)/2);
		 fprintf(fp2,"总计(%d*%d)+%d=%d个汉字 测试累加值为 %d",j-1,8,(i%16)/2,((j-1)*8)+(i%16)/2,i/2);
		}
		fprintf(fp2,"%c%c",0x0d,0x0a);
	}
	fprintf(fp2,"%c%c",0x0d,0x0a);
//===========================================================================================
	//写入汉字内码表对应的点阵表
	m=0;//最大限制值
	fseek(fp1,0,0);							//文件指针指向开头第1字节
	un.st.b=fgetc(fp1);						//取汉字的第一个字节
	un.st.a=fgetc(fp1);						//取汉字的第二个字节
	if(ch=='c'||ch=='C')						//C51格式的点阵数据
	{
		fprintf(fp2,"//汉字内码表对应点阵,每行1个汉字24字节:");			
		fprintf(fp2,"%c%c",0x0d,0x0a);
		fprintf(fp2,"uchar code hzdz [ ][%d] = {",HZDZ_LEN);
		fprintf(fp2,"%c%c",0x0d,0x0a);
		while(1)
		{
			if(feof(fp1))
			{
				cout<<"\nThe FILE1.TXT have finished!\n";
				break;					//点阵提取结束
			}			
			un0.ll=gethzdz(un.ab);				//取该汉字的24字节点阵数据
			m++;
			if(un0.ll==0xb020)				//读HZK12文件到结尾,返回一个数作为标志
				break;					//'啊'的内码-0xA1A1=0xB040
			//------------------------------------------------
			//hanzi_view();					//查看24字节汉字点阵的外形是不是刚才读取的汉字
			//------------------------------------------------
			//将这个汉字的点阵数据写入目标文件
			fgetc(fp1);					//注意fp加1了,后面需要fseek(fp1,-1L,1);
			for(int i=0;i<(HZDZ_LEN-1);i++)
			{
			 fprintf(fp2,"0x%.2x%c",hzdz[i],',');
			 //if(i==12)
			 //	fprintf(fp2,"%c%c",0x0d,0x0a);
			}
			if(feof(fp1))					//这个判断必需上一句fgetc(fp1);
			{
		    	 fprintf(fp2,"0x%.2x}",hzdz[i]);		//结束时数据尾不需要有逗号了
			}
			else
			 fprintf(fp2,"0x%.2x%c",hzdz[i],',');
			fprintf(fp2,"%c%c",0x0d,0x0a);
			///-------------------------------------------
			//view 观察
			Form1->Memo1->Text=printf("\ntotal  m = %d\n",m);

			Form1->Memo1->Text=printf("\nposition = %x",un0.st0.d);
			Form1->Memo1->Text=printf("%x",un0.st0.c);
			Form1->Memo1->Text=printf("%x",un0.st0.b);
			Form1->Memo1->Text=printf("%0.2xH BYTE\n	 = 32*((FIRST-0xA1)*94+(SECOND-0xA1))\n",un0.st0.a);
			cout<<"\ncontinue(y/n)?\n";

			//ch=getch();
			//if(ch=='n'||ch=='N')
			//	break;
			//--------------------------------------------------------------------------
			if(m>=7000)		 			//限制最多提取7000个汉字,比国标还多,够了吧?国标只有6000多个
			{
				fprintf(fp2,"不会吧,你的汉字库比国标还大?\n");
				break;		 			//如果汉字库没有错,根本不会从这里退出
			}
			fseek(fp1,-1L,1);				//这里要减去1,因为前面有fgetc(fp1);
			un.st.b=fgetc(fp1);	 			//取汉字内码第1字节
			un.st.a=fgetc(fp1);	 			//取汉字内码第2字节
		}
	}
	else								//汇编格式的点阵数据
	{
		fprintf(fp2,";汉字内码表对应点阵,每行1个汉字(24字节)"); 
		fprintf(fp2,"%c%c",0x0d,0x0a);
		fprintf(fp2,"hzdz_addr:");
		fprintf(fp2,"%c%c",0x0d,0x0a);
		while(1)
		{
			if(feof(fp1))					//检测FILE1.TXT文件是否结束
			{
			 cout<<"\nThe FILE1.TXT have finished!\n";
			 break;					//点阵提取结束
			}
			un0.ll=gethzdz(un.ab);				//取该汉字的24字节点阵数据
			m++;
			if(un0.ll==0xb020)				//读HZK12文件到结尾,返回一个数作为标志
				break;					//'啊'的内码-0xA1A1=0xB040
			//------------------------------------------------
			//hanzi_view();					//查看24字节汉字点阵的外形对照读取的汉字
			//------------------------------------------------
			//将这个汉字的点阵数据写入文件
			for(int i=0;i<HZDZ_LEN;)
			{
				if(!i)
					fputs("DB ",fp2);
				fprintf(fp2,"0%.2xH%c",hzdz[i],',');
				i++;

				fprintf(fp2,"0%.2xH",hzdz[i]);
				i++;
				if(i<(HZDZ_LEN-1))
					fputc(',',fp2);
			}
			fprintf(fp2,"%c%c",0x0d,0x0a);//回车
			///-------------------------------------------
			//view 观察
			printf("\ntotal  m = %d \n",m);

			printf("\nposition = %x",un0.st0.d);
			printf("%x",un0.st0.c);
			printf("%x",un0.st0.b);
			printf("%xH BYTE\n	 = 32*((FIRST-0xA1)*94+(SECOND-0xA1))\n",un0.st0.a);
			cout<<"\ncontinue(y/n)?\n";
			
			//ch=getch();
			//if(ch=='n'||ch=='N')
			//	break;
			//--------------------------------------------------------------------------
			if(m>=7000)					//限制最多提取7000个汉字,比国标还多,够了吧?国标只有6000多个
			{
				fprintf(fp2,"不会吧,你的汉字库比国标还大?\n");
				break;		 			//如果汉字库没有错,根本不会从这里退出
			}
			un.st.b=fgetc(fp1);	 			//取汉字内码第1字节
			un.st.a=fgetc(fp1);	 			//取汉字内码第2字节
		}
	}
	fclose(fp1);
	fclose(fp2);
	cout<<"\nPress any key to exit "<<endl;
	getch();
	return;
}
//===================================================================================================
/*
函数功能:计算获取汉字内码对应的24字节的点阵数据
计算公式:该汉字在点阵字库HZK12里存放的位置=([汉字的第1字节-0xA1]*94+[汉字的第2字节-0xA1])*24 字节
同样,     该汉字在点阵字库HZK16里存放的位置=([汉字的第1字节-0xA1]*94+[汉字的第2字节-0xA1])*32 字节
明白了吧? 16*16点阵每个汉字需要(16*16)/8=32字节空间,12*12点阵每个汉字需要(12*16)/8=24字节的空间,每
行有4个点是没有用的,即每行第2个字节有4位无点阵数据,实际上每个汉字可以压缩成(12*12)/8=18字节.
*/
unsigned long gethzdz(unsigned int n)
{
	FILE *fp;
	static unsigned long m=0xb020;
	unsigned long j,k;            	//如何定义可以实现最小的内存占用?
	char i;
	union word
	{
		unsigned int ab;
		struct bytes
		{
			unsigned char a;
			unsigned char b;
		}st;
	}un;
	//***********************************
	//start
	if((fp=fopen("HZK12","rb"))==NULL)
//	if((fp=fopen("HZK16","rb"))==NULL)
	{
		cout<<"Read HZK16 error !\n";
		cout<<"Press any key to exit!";
		getch();
		return m ;
	}
	//************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -