📄 ccc.cpp
字号:
{
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 + -