小白写的基于哈夫曼树的解压缩程序,解压时遇到了困难请问
小白写的基于哈夫曼树的解压缩程序,解压时遇到了困难请教
如题
第一张图,原本的txt文档

第二张图,该程序压缩后解压出来的txt

下面是压缩和解压的函数,有点长,希望可以帮我找下错误,谢谢。
------解决思路----------------------
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
如题
第一张图,原本的txt文档
第二张图,该程序压缩后解压出来的txt
下面是压缩和解压的函数,有点长,希望可以帮我找下错误,谢谢。
void compress()
{
depth=0;
for(int i=0;i<MAX_CHARS;i++)
{
dictionary[i].clear();
path[i]='\0';
}
char inFilePath[MAX_PATH];
cin.get();
cout<<"请输入待压缩文件的路径(默认为程序所在的根目录):";
cin.getline(inFilePath,MAX_PATH);
ifstream inFile;
inFile.open(inFilePath);
if(!inFile.is_open())
{
cout<<"Could not open the file "<<inFilePath<<endl;
cout<<"Program terminating."<<endl;
exit(EXIT_FAILURE);
}
cout<<"正在压缩......"<<endl;
long long wgt_per_ch[MAX_CHARS]={0};//存储每个字符的权重
char ch[MAX_CHARS];//存储所有字符
for(int i=0;i<MAX_CHARS;i++)
{
ch[i]=i;
}
inFile>>noskipws;
char value;
do
{
inFile>>value;
for(int i=0;i<MAX_CHARS;i++)
{
if(value==ch[i])
wgt_per_ch[i]++;
}
}
while(inFile.good());
inFile.close();
int ch_occur_size=0;
for(int i=0;i<MAX_CHARS;i++)
{
if(wgt_per_ch[i]>0)
ch_occur_size++;
}
char ch_occur[ch_occur_size];
long long wgt_ch_occur[ch_occur_size];
for(int i=0,j=0;i<MAX_CHARS;i++)
{
if(wgt_per_ch[i]>0)
{
ch_occur[j]=ch[i];
wgt_ch_occur[j]=0;
wgt_ch_occur[j++]=wgt_per_ch[i];
}
}
HuffTree<char>* TreeArray[ch_occur_size];
for(int i=0;i<ch_occur_size;i++)
{
TreeArray[i]=new HuffTree<char>(ch_occur[i],wgt_ch_occur[i]);
}
HuffTree<char>* hftree = buildHuff(TreeArray,ch_occur_size);
huffman_code(hftree->root(),ch_occur);
//存储词频:新建存储压缩数据的文件,首先写入不同字符的个数,然后将每个字符及其对应的词频写入文件。
ofstream outFile;
char outFilePath[MAX_PATH];
strcpy(outFilePath,inFilePath);
strcat(outFilePath,".hz");
outFile.open(outFilePath);
outFile<<ch_occur_size<<endl;
for(int i=0;i<ch_occur_size;i++)
{
outFile<<int(ch_occur[i])<<"-"<<dictionary[i]<<endl;
}
ifstream inFile2;
inFile2.open(inFilePath);
if(!inFile2.is_open())
{
cout<<"Could not open the file "<<inFilePath<<endl;
cout<<"Program terminating."<<endl;
exit(EXIT_FAILURE);
}
char val;
int pos=0;//位运算操作的位置
char in=0;
inFile2>>noskipws;
do
{
inFile2>>val;
for(int i=0;i<ch_occur_size;i++)
{
if((int(val))==(int(ch_occur[i])))
{
for(int j=0;j<(dictionary[i].size());j++)
{
if(dictionary[i][j]=='1')
{
in|=1<<(7-(pos%8));
}
pos++;
if(pos%8==0)
{
outFile<<in;
in=0;
}
}
}
}
}
while(inFile2.good());
inFile2.close();
outFile.close();
cout<<"压缩完成!"<<"文件位于(默认为程序所在的根目录):"<<outFilePath<<endl;
}
void decompress()
{
char inFilePath[MAX_PATH];
cin.get();
cout<<"请输入待解压文件的路径(默认为程序所在的根目录):";
cin.getline(inFilePath,MAX_PATH);
ifstream inFile;
inFile.open(inFilePath);
if(!inFile.is_open())
{
cout<<"Could not open the file "<<inFilePath<<endl;
cout<<"Program terminating."<<endl;
exit(EXIT_FAILURE);
}
cout<<"正在解压......"<<endl;
int value_num;
inFile>>value_num;
int ch_occur_size=value_num;
char ch_occur[ch_occur_size];
string huffman_code[ch_occur_size];
for(int i=0;i<ch_occur_size;i++)
{
int val_num;
string val;
inFile>>val_num;
inFile>>val;
ch_occur[i]=val_num;
huffman_code[i]=&(val[1]);
}
string bit_code;
int pos=0;
char value;
inFile>>noskipws;
inFile>>value;//读取非文档内容最后一个回车
inFile>>value;
ofstream outFile;
char outFilePath[MAX_PATH];
char temp1[MAX_PATH]={'\n'};
char temp2[MAX_PATH]={'\n'};
int mark=0;
for(int i=0;i<strlen(inFilePath)-1;i++)
{
if('.'!=inFilePath[i])
{
temp1[i]=inFilePath[i];
}
else
{
mark=i;
break;
}
}
for(int i=mark,j=0;i<strlen(inFilePath);i++)
{
temp2[j++]=inFilePath[i];
}
temp2[strlen(temp2)-3]='\0';
strcat(temp1,"(restore)");
strcat(temp1,temp2);
strcpy(outFilePath,temp1);
outFile.open(outFilePath);
do
{
if(value&1<<(7-(pos%8)))
{
bit_code+='1';
}
else
{
bit_code+='0';
}
pos++;
if(pos%8==0)
{
inFile>>value;
}
for(int i=0;i<ch_occur_size;i++)
{
if(bit_code==huffman_code[i])
{
outFile<<ch_occur[i];
bit_code.clear();
}
}
}
while(inFile.good());
inFile.close();
outFile.close();
cout<<"解压完成!"<<"文件位于:"<<outFilePath<<endl;
}
------解决思路----------------------
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。