用C++编写的文件压缩解压程序.docx
《用C++编写的文件压缩解压程序.docx》由会员分享,可在线阅读,更多相关《用C++编写的文件压缩解压程序.docx(37页珍藏版)》请在冰豆网上搜索。
用C++编写的文件压缩解压程序
//-----------------------------------------------------------------------------
//huffmantreemain.cpp
//主界面
#include"huffmantree.h"
#include
#include
#include"compress1.h"
#include"Ceshi.h"
voidmenu()
{
cout< cout<<"\t\t ***操作菜单***\n\n";
cout<<"\t\t\t1压缩文件\n";
cout<<"\t\t\t2解压文件\n";
cout<<"\t\t\t3测试\n";
cout<<"\t\t\t0退出\n\n\n\n";
return;
}
intmain()
{
charmeiyong;
cout<<"\n\n\n\n\n\n\n\n\n"
<<"\t &*************** 压缩软件 **************&\n"
<<"\t * *\n"
<<"\t * *\n"
<<"\t * *\n\n\n"
<<"\t * 运行本软件之前,请务必仔细阅读使用指南 *"
<<"\n\n\n\n\n\n\n\n\n\n";
cin.unsetf(ios:
:
skipws);
cin>>meiyong;
cin.setf(ios:
:
skipws);
ifstreamfin("使用说明.txt",ios:
:
binary);
fin.unsetf(ios:
:
skipws);
while(fin>>meiyong)
{
cout< }
cout< getch();
fin.setf(ios:
:
skipws);
fin.close();
cout<<"\n\n\n\n\n\n";
cout<<"\n";
cout<<"\t\t*-------------------------------------------*\n";
cout<<"\t\t* 实验六:
霍夫曼树的应用 *\n";
cout<<"\t ******* *******\n";
cout<<"\t\t* 作者:
gdgzzch 学号:
15201314 *\n";
cout<<"\t\t*-------------------------------------------*\n\n";
cout<<"\t\t 2005.11.16\n\n";
menu();
intchoice;
cout<<"请选择操作:
";
cin>>choice;
while
(1)
{
switch(choice)
{
case1:
Compress();
break;
case2:
Decompress();
break;
case3:
Ceshi();
break;
case0:
cout<<"\n\n\t\t********* 谢谢您使用本软件,再见!
***********\n\n\n\n";
return1;
default:
cout<<"无此操作!
\n\n";
}
cout<";
cin>>choice;
}
return1;
}
//----------------------------------------------------------
//compress1.h
//压缩
#ifndefCOMPRESS
#defineCOMPRESS
#include"huffmantree.h"
#include
#include
#include
#include
//压缩函数
voidCompress()
{
unsignedcharch;
inti,j,k;
intCharnum[256];//
unsignedcharChars[256]; //与下面共同使用,记录字符
intCharnums[256]; //记录对应字符的个数
intCharKinds; //字符种数
charfilenameorg[21]; //文件名不超过20个字符源文件名
charfilenameaim[21]; //目标文件名
intfileorgsize;//源文件大小
intfileaimsize;//压缩文件大小
HuffmanTreeht;
CharNameNodeNameNode[256]; //存储字符对应的霍夫曼编码
BinTreeNode*btn=NULL;
Code*first=NULL;
Code*last=NULL;
ifstreamfilein;
ofstreamfileout;
cout<<"请输入你要压缩的文件的名字:
";
cin>>filenameorg;
filein.open(filenameorg,ios:
:
nocreate|ios:
:
binary); //open:
filenameorg
if(!
filein)
{
cout<\n";
filein.clear();
return;
}
cout<<"请输入你的压缩文件的名字(*.HFM):
"; //以后再用
cin>>filenameaim;
charfiletype[5];
intlen;
len=strlen(filenameaim);
if(len<=4)
{
cout< return;
}
for(i=len-1,j=3;i>=len-4;i--,j--)
filetype[j]=filenameaim[i];
filetype[4]='\0';
if(strcmp(filetype,".HFM")!
=0)
{
cout< return;
}
// ******************************************************
for(i=0;i<256;i++)
{
Charnum[i]=0; //记录每一个字符的个数
Charnums[i]=0; //记录字符Char[i]的个数
}
filein.unsetf(ios:
:
skipws);
fileorgsize=0; //计算源文件大小
while(filein>>ch)
{
Charnum[unsignedint(ch)]++; //统计每种字符的频数
fileorgsize++;
}
filein.setf(ios:
:
skipws);
filein.close(); //close:
filenameorg
// ******************************************************
j=0;
for(i=0;i<256;i++)
{
if(Charnum[i])
{
Chars[j]=unsignedchar(i); //统计源文件中存在的字符的
Charnums[j]=Charnum[i];
j++;
}
}
CharKinds=j;
// ******************************************************
fileaimsize=0;//计算压缩文件大小
fileout.open(filenameaim,ios:
:
binary);
fileout<<'0'<<''; //非法位数(之后修改)
fileout< fileout< fileaimsize+=7;
for(i=0;i {
fileout< fileaimsize+=10;
}
ht.Build(Charnums,Chars,CharKinds,ht); //建立霍夫曼树
i=0;
ht.Path(ht.GetRoot(),first,last,NameNode,i);//搜索霍夫曼树求得字符对应的霍夫曼编码
// ***********************************************************
filein.open(filenameorg,ios:
:
nocreate|ios:
:
binary);
filein.unsetf(ios:
:
skipws);
k=0;
j=0;
while(filein>>ch)
{
i=0;
while(ch!
=NameNode[i].charname) //找到ch
i++;
Code*p=NameNode[i].link;
while(p!
=NULL)
{
j<<=1;
j+=p->code;
k++;
if(k==8)
{
fileout< fileaimsize++; //计算压缩文件大小
k=0;
j=0;
}
p=p->link;
}
}
filein.setf(ios:
:
skipws);
filein.close();
if(k<8)
{
j<<=(8-k);
fileout< fileaimsize++; //计算压缩文件大小
}
fileout.seekp(0,ios:
:
beg);
fileout<<8-k; //修改非法代码的位数
fileout.close();
for(i=0;i {
Code*q=NameNode[i].link;
Code*s=NULL;
while(q!
=NULL)
{
s=q;
q=q->link;
deletes;
}
NameNode[i].link=NULL; //清除链表信息
}
ht.Destroy();
cout<<"文件压缩成功!
压缩率为:
"<<(fileaimsize*100)/fileorgsize<<'%'<
return;
}
voidDecompress()
{
unsignedcharch;
inti,j,k;
unsignedcharChars[256]; //与下面共同使用,记录字符
intCharnums[256]; //记录对应字符的个数
intCharKinds; //字符种数
unsignedinttotal; //记录字符转化后的数
intfpend; //暂存文件指针的最后位置
charfilenameorg[21]; //文件名不超过20个字符源文件名
charfilenameaim[21]; //目标文件名
HuffmanTreeht;
CharNameNodeNameNode[256]; //存储字符对应的霍夫曼编码
BinTreeNode*btn=NULL;
Code*first=NULL;
Code*last=NULL;
ifstreamfilein;
ofstreamfileout;
charfiletype[5];
intlen;
cout<<"请输入你要解压的文件的名字:
";
cin>>filenameorg;
len=strlen(filenameorg);
if(len<=4)
{
cout<\n";
return;
}
for(i=len-1,j=3;i>=len-4;i--,j--)
filetype[j]=filenameorg[i];
filetype[4]='\0';
if(strcmp(filetype,".HFM")!
=0)
{
cout<\n";
return;
}
filein.open(filenameorg,ios:
:
nocreate|ios:
:
binary);
if(!
filein)
{
cout<\n";
filein.clear();
return;
}
filein.close();
/* cout<<"请输入你解压后的文件的名字:
";
cin>>filenameaim;*/
filein.open(filenameorg,ios:
:
nocreate|ios:
:
binary);
if(!
filein)
{
cout<<"解压失败,请重试!
\n";
filein.clear();
return;
}
filein.seekg(0,ios:
:
end);
fpend=filein.tellg(); //记录文件尾的位置
filein.seekg(0,ios:
:
beg); //恢复
filein.unsetf(ios:
:
skipws);
filein>>k>>ch; //最后一个字符不合法的位数
filein>>filenameaim>>ch;
filein>>CharKinds>>ch;
for(i=0;i filein>>Chars[i]>>ch>>Charnums[i]>>ch; //载入字符信息
ht.Build(Charnums,Chars,CharKinds,ht); //建立霍夫曼树
btn=ht.GetRoot();
fileout.open(filenameaim,ios:
:
binary); //以文本文件打开
if(!
fileout)
{
cout<<"目标文件创建失败,请重试!
\n";
fileout.clear();
return;
}
while(filein>>ch)
{
total=(unsignedint)(ch); //这里都是正确的
j=0;
if(filein.tellg()==fpend) //到了文件尾
j=k; //留k位不输出
for(i=7;i>=j;i--)
{
if(total&(1<
btn=btn->GetRight();
else
btn=btn->GetLeft();
// if(btn->GetData()!
=0)
if(btn->GetLeft()==NULL&&btn->GetRight()==NULL)
{
fileout<GetData();
btn=ht.GetRoot();
}