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

📄 ccc.cpp

📁 不是
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{ 
			cout<<"不能打开文件"<<endl; 
		} 

	tran=(char*)malloc(100*sizeof(char));//申请100个字符空间 
	while(i==99) 
		{ 
			fgets(tran,i,tobetran); //从tobetran文件中得到99个字符,第100个字符为‘\0’,放到tran字符串中
				
				for(i=0;*(tran+i)!='\0';i++) 
					{ 
					for(j=1;j<=n;j++) 
						{ 
							if(*(ID+j)==*(tran+i)) //如果ID字符串中的字符和tran字符串中的字符相等则将对应的编码写到codefile中
								{ 
									fputs(HC[j],codefile); 
									if(j>n) //超出编码则报错
										{ 
											cout<<"字符错误,无法编码!"<<endl; 
											break; 
										} 
								} 
						} 
				} 
		} 
	cout<<"编码工作完成"<<endl<<"编码写入目录下的codefile.txt中"<<endl<<endl; 
	fclose(tobetran); 
	fclose(codefile); 
	fclose(num);
	free(tran); 
	free(HT);
	free(HC);
	free(ID);
	getch();
	system("cls");
} 


/************************************************************************************

							译码函数(把反译的字符放到txtfile.txt中)

*************************************************************************************/
void Decoding() 
{	
	FILE *codef,*txtfile,*num; //将codef中的编码译码后放到txtfile中
	//先将编码字符的总字数读入内存
	int n=0;
	if((num=fopen("num.txt","r"))==NULL) 
	{ 
		cout<<"can not open file"<<endl;
		getch();
		system("cls");
		return; 
	} 
	fscanf(num,"%d",&n);
	

	//现在为赫夫曼树和编码及字符申请空间
	HuffmanTree HT=NULL; //赫夫曼树初始化为空
	HuffmanCode HC=NULL; //赫夫曼编码初始化为空
	char *ID=NULL;//要翻译的字符的存储地址
	int m;
	m=2*n-1;
	HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); 
	HC=(HuffmanCode)malloc((n+1)*sizeof(char *));
	ID=(char *)malloc((n+1)*sizeof(char));//为翻译的节点的ID申请空间

	//再将赫夫曼树和编码及字符读入内存
	readheffmantree(HT,n,ID,m);


	/*************************************************************************/
	//再次求编码

	char *cd; 
	int f,start,i,c;
	cd=(char *)malloc(n*sizeof(char));	//分配求编码的空间
	cd[n-1]='\0';							//编码结束符
	for(i=1;i<=n;i++)						//逐个字符求赫夫曼编码
		{ 
			start=n-1;						//编码结束位置
			for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// 从叶子到根逆向求编码
				if(HT[f].lchild==c) cd[--start]='0'; 
				else cd[--start]='1'; 
			HC[i]=(char *)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 
			strcpy(HC[i],&cd[start]); //从cd复制编码(串)到HC,HC[i]中存储的是第i个节点的编码
		} 
	free(cd);						//释放空间 

/********************************************************************************/


	system("cls");
	cout<<"下面对根目录下文件codefile.txt中的字符进行译码"<<endl; 

	if((txtfile=fopen("txtfile.txt","w"))==NULL) 
	{ 
		cout<<"不能打开文件"<<endl; 
	} 
	if ((codef=fopen("codefile.txt","r"))==NULL) 
	{ 
		cout<<"不能打开文件"<<endl; 
	} 
	char work[100000],work2[100000],i2; 
	int i4=0,s;
	unsigned long length=10000; 
	fgets(work,length,codef); //将codef中的前10000个字符放到work,中其中存储的是需要反译的码
	s=2*n-1; //赫夫曼数节点的总数
	 //codefile.txt中一个字符一个字符的放到i中比较,将work中的
	//编码反译后放到work2中去
	for(i=0;work[i-1]!='\0';i++) 
	{  
		i2=work[i];	
		if(HT[s].lchild==0||HT[s].rchild==0) //此时说明到了叶子节点(s号叶子节点)第一次循环是根节点
			{ 
				work2[i4]=*(ID+s); //就将s号叶子节点的字符值付给work2字符组
				i4++; 
				s=2*n-1;//找到一个字符后再从根节点开始下一次循环 
				i--;
			} 		
			else if(i2=='0') {s=HT[s].lchild;} //如果i2是0就顺着左子树向下找
			else if(i2=='1') {s=HT[s].rchild;} //如果i2是1就顺着右子树向下找
			else
			break;
	} 
	work2[i4]='\0'; 
	fputs(work2,txtfile);
	//将反译后的字符存放在txtfile.txt中
	cout<<"译码完成"<<endl<<"内容写入根目录下的文件txtfile.txt中"<<endl<<endl; 
	
	fclose(txtfile); 
	fclose(codef); 
	fclose(num);
	free(HT);
	free(HC);
	free(ID);
	getch();
	system("cls");
} 



/************************************************
				打印编码的函数
************************************************/ 
void Code_printing() 
{ 
	system("cls");
	cout<<"下面打印根目录下文件CodePrin.txt中编码字符"<<endl; 
	FILE * CodePrin,* codefile; 
	if((CodePrin=fopen("CodePrin.txt","w"))==NULL) 
	{ 
		cout<<"不能打开文件"<<endl; 
		return; 
	} 
	if((codefile=fopen("codefile.txt","r"))==NULL) 
	{ 
		cout<<"不能打开文件"<<endl; 
		return; 
	} 

	char *work3; 
	work3=(char*)malloc(10000*sizeof(char)); //申请51个字符空间
	if(fgets(work3,10000,codefile)==NULL) //将codefile中的50个字符写到work3中去
		{ 
		cout<<"不能读取文件"<<endl; 
		}					
	fputs(work3,CodePrin); //将work3中的字符写到CodePrin文件中
	puts(work3); //打印50个字符
	free(work3); 
	cout<<"打印工作结束"<<endl<<endl; 
	fclose(CodePrin); 
	fclose(codefile); 
	getch();
	system("cls");
} 



/*********************************************************
					打印译码函数(同上)
**********************************************************/
void Code_printing1() 
{ 
	system("cls");
	cout<<"下面打印根目录下文件txtfile.txt中译码字符"<<endl; 
	FILE * CodePrin1,* txtfile; 
	if((CodePrin1=fopen("CodePrin1.txt","w"))==NULL) 
	{ 
		cout<<"不能打开文件"<<endl; 
		return; 
	} 
	if((txtfile=fopen("txtfile.txt","r"))==NULL) 
	{ 
		cout<<"不能打开文件"<<endl; 
		return; 
	} 
	char *work5; 
	work5=(char*)malloc(51*sizeof(char)); 
	do 
	{ 
		if(fgets(work5,51,txtfile)==NULL) 
		{ 
		cout<<"不能读取文件"<<endl; 
		break; 
		} 
	fputs(work5,CodePrin1); 
	puts(work5); 
	}while(strlen(work5)==50); 
	
	cout<<"打印工作结束"<<endl<<endl; 
	fclose(CodePrin1); 
	fclose(txtfile); 
	free(work5); 
	getch();
	system("cls");
} 


/****************************************************************************

						打印赫夫曼函数

*****************************************************************************/
void coprint(HuffmanTree start,HuffmanTree HT,int numb) 
{	
	if(start!=HT) //判断赫夫曼树有没有到达叶子节点,如果赫夫曼树没有到达叶子节点
	{ 
		FILE * TreePrint; 

		if((TreePrint=fopen("TreePrint.txt","a"))==NULL) 
		{cout<<"创建文件失败"<<endl;				
		return; 
		} 
		numb++;//该变量为已被声明为全局变量 子树的输出长度当从递归函数返回时上层的numb保持不变是靠下面的numb--完成的
		coprint(HT+start->rchild,HT,numb); //先递归看右子树,直到到达叶子节点
		cout<<setw(5*numb)<<start->weight<<endl; //setw()函数是设置域宽

		fprintf(TreePrint,"%d\n",start->weight); 
		coprint(HT+start->lchild,HT,numb); //再递归看左子树,直到到达叶子节点
		numb--; //保证了当下层的函数返回是numb保持不变
		fclose(TreePrint); 
	} 
} 
void Tree_printing() 
{	
	FILE *num;
	int n=0;
	int numb=0;
	if((num=fopen("num.txt","r"))==NULL) 
	{ 
		cout<<"can not open file"<<endl;
		getch();
		system("cls");
		return; 
	} 
	fscanf(num,"%d",&n);


	//现在为赫夫曼树和编码及字符申请空间
	HuffmanTree HT=NULL; //赫夫曼树初始化为空
	HuffmanCode HC=NULL; //赫夫曼编码初始化为空
	char *ID=NULL;//要翻译的字符的存储地址
	int m;
	m=2*n-1;
	HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); 
	HC=(HuffmanCode)malloc((n+1)*sizeof(char *));
	ID=(char *)malloc((n+1)*sizeof(char));//为翻译的节点的ID申请空间

	//再将赫夫曼树和编码及字符读入内存
	readheffmantree(HT,n,ID,m);

/*************************************************************************/
	//再次求编码

	char *cd; 
	int f,start,i,c;
	cd=(char *)malloc(n*sizeof(char));	//分配求编码的空间
	cd[n-1]='\0';							//编码结束符
	for(i=1;i<=n;i++)						//逐个字符求赫夫曼编码
		{ 
			start=n-1;						//编码结束位置
			for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// 从叶子到根逆向求编码
				if(HT[f].lchild==c) cd[--start]='0'; 
				else cd[--start]='1'; 
			HC[i]=(char *)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 
			strcpy(HC[i],&cd[start]); //从cd复制编码(串)到HC,HC[i]中存储的是第i个节点的编码
		} 
	free(cd);						//释放空间 

	system("cls");
	HuffmanTree p; 
	p=HT+m; //指到根节点,从根节点开始打印
	cout<<"下面打印赫夫曼树"<<endl; 
	coprint(p,HT,numb); 
	cout<<"打印工作结束"<<endl; 
	fclose(num);
	free(HT);
	free(HC);
	free(ID);
	getch();
	system("cls");
} 

void main() 
{ 
	char choice; 
	while(choice!='q') 
	{	
		cout<<"\n******************************"<<endl; 
		cout<<" 欢迎使用赫夫曼编码解码系统"<<endl; 
		cout<<"******************************"<<endl; 
		cout<<"(1)要初始化赫夫曼链表请输入'i'"<<endl; 
		cout<<"(2)要编码请输入'e'"<<endl; 
		cout<<"(3)要译码请输入'd'"<<endl; 
		cout<<"(4)要打印编码请输入'p'"<<endl; 
		cout<<"(5)要打印译码请输入'y'"<<endl; 
		cout<<"(6)要打印赫夫曼树请输入't'"<<endl; 
		cout<<"(7)要推出系统请输入'q'"<<endl;
		cout<<"\n如果没有初始化链表,请先初始化赫夫曼链表,输入'i'"<<endl;
		cin>>choice; 
		switch(choice) 
		{ 
			case 'i': 
			Initialization(); 
			break; 
			case 'e': 
			Encoding(); 
			break; 
			case 'd': 
			Decoding(); 
			break; 
			case 'p': 
			Code_printing(); 
			break; 
			case 'y': 
			Code_printing1(); 
			break; 
			case 't': 
			Tree_printing(); 
			break; 			
			case 'q':
			exit(0);
			default: 
			exit(1); 
			break;
		} 
	}
}

⌨️ 快捷键说明

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