'1';
}
//为每个字符数组分配相应的数量 由于范围的问题要仔细考虑的
HC[i] = (char *)malloc((count+1-start)*sizeof(char));
//参数均为char *
strcpy(HC[i],&cd[start]);
code[i] = huffmanTree[i].data;
}
return HC;
}
/*
将编码表写入默认文件当中,并在结尾存入叶子节点数(count)与压缩后文件的总bit数
1111000 27
...........
...........
#sum_bit##count#
*/
void freToFile(int code[],HCode *HC)
{
int i;
//打开默认文件
FILE *fe = fopen("C:\\dic.txt","wb");
//将编码信息和叶子节点信息写入词典
for(i=1;i<=count;i++)
{
fprintf(fe,"%s %d\n",HC[i],code[i]);
}
char c = '#';
//写入sum_bit
fprintf(fe,"%c",c);
fprintf(fe,"%d",getSumBits());
fprintf(fe,"%c",c);
//写入count
fprintf(fe,"%c",c);
fprintf(fe,"%d",count);
fprintf(fe,"%c",c);
fclose(fe);
}
//由于词频表是按照字符串方式存储的叶子节点信息,读取出来的字符串需要转换成int值再使用
//其中需要使用pow函数,由于pow函数有精度损失,自己写了一个使用
int powmy(int a,int b)
{
if(b==0) return 1;
int i = 0;
int result = 1;
for(;i {
result *=a;
}
return result;
}
/*从编码表文件读取相应信息以用来解压文件,读取信息包括编码和叶子信息*/
HCode* freFromFile(int code[],HCode *HC)
{
int i;
FILE *fe = fopen("C:\\dic.txt","rb");
if(fe==NULL)
{
printf("词典文件不存在!");
return NULL;
}
int k;
int num[10];
int m;
int flag = 0;
char * cd = (char *)malloc((256+1)*sizeof(char));
//读取一个字节
char c = fgetc(fe);
for(i=1;flag!=1;i++)
{
//如果读取到#号键,就跳出循环,继续读取sum_bit和count值
if(c=='#') break;
//每一行的读取直到读到空格,然后就完成了一条huffman编码的读取
int j = 0;
while(c!=' ')
{
cd[j++] = c;
c = fgetc(fe);
}
cd[j] = '\0';
//将读取到的huffman编码存入相应的二维字符数组当中去
HC[i] = (char *)malloc((j+1)*sizeof(char));
strcpy(HC[i],&cd[0]);
//下面直到读取到空格键为止,读取huffman叶子节点信息,读取到的是字符,需要转换成int值
c = fgetc(fe);
k = 0;
while(c!='\n')
{
num[k++] = c-'0';
c = fgetc(fe);
}
code[i] = 0;
m = 0;
//转换成int值,存入code[]数组当中
for(k=k-1;k>=0;k--)
{
code[i]+=num[k]*powmy(10,m);
m++;
}
//继续向下读取
c = fgetc(fe);
}
//获取压缩文件的总bit数,以用来判断最后一次读取的是不是足够8位
c = fgetc(fe);
k = 0;
while(c!='#')
{
num[k++] = c-'0';
c = fgetc(fe);
}
//同样将读取到的char转换成int
m = 0;
sum_bit = 0;
for(k=k-1;k>=0;k--)
{
sum_bit+=(num[k]*powmy(10,m));
m = m + 1;
}
c = fgetc(fe); c = fgetc(fe);//头一个读取#,后一个才开始读取数据
k = 0;
while(c!='#')
{
num[k++] = c-'0';
c = fgetc(fe);
}
//将读取到的char转换成int
m = 0; count = 0;
for(k=k-1;k>=0;k--)
{
count+=num[k]*pow(10,m);
m++;
}
fclose(fe);
return HC;
}
/*压缩文件*/
void compress_file(char* file1,char*file2)
{
int i,sum = 0,flag = 0,j,k = 0;
//数组开设的不够大是最后的一个bug的成因,因为有可能这个Huffman编码很长很长
int eight[1000];
memset(eight,0,1000*sizeof(int));
FILE *fo = fopen(file1,"rb");
FILE *fw = fopen(file2,"wb");
if(fo == NULL||fw == NULL)
{
printf("文件读取失败!");
return;
}
//统计已经压缩的字节总数,用于计算压缩百分比
int aa = 0;
int sum_bytes = getSumBytes();
while(!feof(fo))
{
sum = 0;
int a = fgetc(fo);
//每次读取一个字节就+1
aa++;
//读取了一个字节之后就与编码表进行比较,查找对应的编码
for(i=1;i<=count;i++)
{
if(code[i] == a)
{
//flag作为计数器,当凑够8位之后就作为一个字节写入压缩文件
flag+=strlen(HC[i]);
int len = strlen(HC[i]);
//flag 小于8的时候继续累加,直到凑够8个
if(flag<8)
{
for(j