和解压缩功能。
// 压缩函数 void compress(FILE *fp_in, FILE *fp_out, struct node *root) {
char buffer[MAX_BITS] = {'\0'}; // 初始化缓冲区
int index = 0;
char c;
while ((c = fgetc(fp_in)) != EOF) {
if (c >= 'A' && c <= 'Z') { // 如果是大写字母
struct node *curr = root;
while (curr->c != c) { // 寻找对应的叶子节点
if (buffer[index++] == '0') {
curr = curr->left;
} else {
curr = curr->right;
}
}
strcat(buffer, code); // 将编码加入到缓冲区中
while (strlen(buffer) >= MAX_BITS) { // 当缓冲区满时输出到文件中
unsigned char byte = 0; // 使用一个字节存储数据
for (int i = 0; i < MAX_BITS; i++) {
byte <<= 1; // 左移一位,相当于乘以2
if (buffer[i] == '1') { // 如果该位为1则加上1
byte |= 1;
}
}
fwrite(&byte, sizeof(unsigned char), 1, fp_out); // 将字节写入文件中
memmove(buffer, buffer + MAX_BITS, strlen(buffer) - MAX_BITS + 1); // 移除已经处理的部分,保留未处理的部分继续处理
}
}
}
if (index > 0) { // 处理剩余的部分
strcat(buffer, code);
int padding = MAX_BITS - strlen(buffer); // 计算需要补充的位数
for (int i = 0; i < padding; i++) {
buffer[strlen(buffer)] = '0'; // 在缓冲区末尾添加0
}
unsigned char byte = 0;
for (int i = 0; i < MAX_BITS; i++) {
byte <<= 1;
if (buffer[i] == '1') {
byte |= 1;
}
}
fwrite(&byte, sizeof(unsigned char), 1, fp_out); // 将字节写入文件中
}
}
// 解压函数 void decompress(FILE *fp_in, FILE *fp_out, struct node *root) {
struct node *curr = root;
unsigned char byte;
while (fread(&byte, sizeof(unsigned char), 1, fp_in) != EOF) { // 每次读取一个字节
for (int i = MAX_BITS - 1; i >= 0; i--) { // 对每个位进行处理
if (byte & (1 << i)) { // 如果该位为1,则向右走,否则向左走
curr = curr->right;
} else {
curr = curr->left;
}
if (!curr->left && !curr->right) { // 如果到达叶子节点,则输出对应的字符,并重置当前节点为根节点继续处理下一个字符
fprintf(fp_out, "%c", curr->c);
curr = root;
}
}
}
}