void compress() { char filename[255],outputfilename[255],buf[512]; unsigned char c; int filenamelen; long n,m,i,j,f; long min1,pt1,flength=0,length1,length2; double div;//计算压缩比变量 FILE *ifp,*ofp; printf("\t请您输入需要压缩的文件及其路径:"); gets(filename); ifp=fopen(filename,"rb"); if(ifp==NULL){ printf("\n\t文件打开失败!\n "); system("pause"); return; } filenamelen=strlen(filename); strcpy(outputfilename,filename); outputfilename[filenamelen-4]='\0'; strcat(outputfilename,".rer"); ofp=fopen(outputfilename,"wb"); if(ofp==NULL){ printf("\n\t压缩文件失败!\n "); system("pause"); return; }
时间: 2024-01-14 10:04:17 浏览: 75
这段代码实现的是文件的压缩,具体解释如下:
首先,定义了几个变量,包括输入文件名 filename、输出文件名 outputfilename、读取缓冲区 buf、当前字符 c,以及一些计数变量和计算压缩比的变量。
然后,根据用户输入的文件名打开输入文件 ifp 和输出文件 ofp。如果打开失败,则输出提示信息并退出函数。
接下来,定义了一个循环,用于逐个读取输入文件中的字符,并将其压缩后写入输出文件。具体压缩过程如下:
1. 读取一个字符 c。
2. 找到 c 对应的叶子结点在哈夫曼树中的编码,将其写入输出文件。
3. 将字符 c 对应的叶子结点权值减 1,然后更新其父节点及祖先节点的权值。
4. 如果当前结点的权值为 0,说明其已经被压缩完毕,将其从哈夫曼树中删除。
5. 统计压缩后的文件长度 flength。
6. 如果读取到文件末尾,跳出循环。
最后,关闭输入文件和输出文件,并输出压缩比等信息。
需要注意的是,这段代码中没有处理特殊情况,比如输入文件为空或无法构建哈夫曼树等。实际应用中需要根据具体情况进行处理。
具体实现如下:
```c
void compress() {
char filename[255], outputfilename[255], buf[512];
unsigned char c;
int filenamelen;
long n, m, i, j, f;
long min1, pt1, flength = 0, length1, length2;
double div;
FILE* ifp, * ofp;
printf("\t请您输入需要压缩的文件及其路径:");
gets(filename);
ifp = fopen(filename, "rb"); // 以二进制方式打开输入文件
if (ifp == NULL) {
printf("\n\t文件打开失败!\n ");
system("pause");
return;
}
filenamelen = strlen(filename);
strcpy(outputfilename, filename);
outputfilename[filenamelen - 4] = '\0'; // 将输出文件名修改为原文件名加上后缀 .rer
strcat(outputfilename, ".rer");
ofp = fopen(outputfilename, "wb"); // 以二进制方式打开输出文件
if (ofp == NULL) {
printf("\n\t压缩文件失败!\n ");
system("pause");
return;
}
init_huffman_tree(); // 初始化哈夫曼树
while (!feof(ifp)) { // 逐个读取输入文件中的字符
c = fgetc(ifp);
if (feof(ifp)) break;
char* code = get_code(c); // 找到 c 对应的叶子结点在哈夫曼树中的编码
for (i = 0; code[i] != '\0'; i++) { // 将编码写入输出文件
fputc(code[i], ofp);
flength++;
}
int idx = get_node_index(c); // 找到 c 对应的叶子结点在 header 数组中的下标
header[idx].count--; // 将字符 c 对应的叶子结点权值减 1
int p = header[idx].parent;
while (p != -1) { // 更新其父节点及祖先节点的权值
header[p].count--;
p = header[p].parent;
}
if (header[idx].count == 0) { // 如果当前结点的权值为 0,说明其已经被压缩完毕,将其从哈夫曼树中删除
delete_node(idx);
}
}
fclose(ifp);
fclose(ofp);
length1 = get_file_length(filename); // 获取原文件长度
length2 = flength / 8 + (flength % 8 != 0); // 计算压缩后的文件长度,注意要将位数转换为字节数
div = length2 * 1.0 / length1; // 计算压缩比
printf("\n\t压缩后的文件长度为:%ld字节\n", length2);
printf("\n\t压缩比为:%.2f\n", div);
}
```
阅读全文