我真的不知道如何缩短代码所以我把整个事情放在下面,但当我运行代码并尝试压缩它时,它会继续运行,当我使用ctrl + z停止它时生成的输出文件大于我试图压缩的文件。我认为错误来自我的压缩文件功能,但下面是整个代码。它编译并运行,但它不是我所期望的。它也没有打印出我在compressFile函数中的语句。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define len(x) ((int)log10(x)+1)
struct node{
int value;
char letter;
struct node *left, *right;
};
typedef struct node Node;
int engLetterFreq[27] = {81, 15, 28, 43, 128, 23, 20, 61, 71, 2, 1, 40, 24, 69, 76, 20, 1, 61, 64, 91, 28, 10, 24, 1, 20, 1, 130};
int findSmaller (Node *array[], int differentFrom){ //start findSmaller
int smaller;
int i = 0;
while(array[i]->value== -1)
i++;
smaller = i;
if(i == differentFrom){
i++;
while(array[i]->value== -1)
i++;
smaller = i;
}
for(i=1; i<27; i++){
if(array[i]->value== -1)
continue;
if(i==differentFrom)
continue;
if(array[i]->value<array[smaller]->value)
smaller = i;
}
return smaller;
}//end findSmaller
void buildHuffmanTree(Node **tree){ //start buildHuffmanTree
Node *temp;
Node *array[27];
int i;
int subTrees = 27;
int smallOne, smallTwo;
for(i=0; i<27; i++){
array[i] = malloc(sizeof(Node));
array[i]->value = engLetterFreq[i];
array[i]->letter = i;
array[i]->left = NULL;
array[i]->right = NULL;
}
while(subTrees>1){
smallOne = findSmaller(array, -1);
smallTwo = findSmaller(array, smallOne);
temp = array[smallOne];
array[smallOne] = malloc(sizeof(Node));
array[smallOne]->value=temp->value+array[smallTwo]->value;
array[smallOne]->letter=127;
array[smallOne]->left=array[smallTwo];
array[smallOne]->right=temp;
array[smallTwo]->value = -1;
subTrees--;
}
*tree = array[smallOne];
return;
}
void fillTable(int codeTable[], Node *tree, int Code){
if(tree->letter<27){
codeTable[(int)tree->letter] = Code;
}else{
fillTable(codeTable, tree->left, Code*10+1);
fillTable(codeTable, tree->right, Code*10+2);
}
return;
}
void compressFile(FILE *input, FILE *output, int codeTable[]){
char bit, c, x = 0;
int n, length, bitsLeft = 8;
int originalBits = 0;
int compressedBits = 0;
while((c=fgetc(input))!=10){
originalBits++;
if(c==32){
length = len(codeTable[26]);
n = codeTable[26];
}else{
length = len(codeTable[c-97]);
n = codeTable[c-97];
}
while(length>0){
compressedBits++;
bit = n % 10 - 1;
n /= 10;
x = x | bit;
bitsLeft--;
length--;
if(bitsLeft == 0){
fputc(x, output);
x = 0;
bitsLeft = 8;
}
x = x << 1;
}
}
if(bitsLeft != 8){
x = x << (bitsLeft-1);
fputc(x, output);
}
printf("Original bits = %d\n", originalBits*8);
printf("Compressed bits = %d\n", compressedBits);
printf("Saved %.2f of memory\n", ((float)compressedBits/(originalBits*8))*100);
return;
}
void decompressFile(FILE *input, FILE *output, Node *tree){
Node *current = tree;
char c, bit;
char mask = 1 << 7;
int i;
while ((c=fgetc(input))!=EOF){
for(i=0; i<8; i++){
bit = c & mask;
c = c << 1;
if(bit==0){
current = current->left;
if(current->letter != 127){
if(current->letter == 26){
fputc(32, output);
}else{
fputc(current->letter+97, output);
}
current = tree;
}
}else{
current = current->right;
if(current->letter != 127){
if(current->letter == 26){
fputc(32, output);
}else{
fputc(current->letter+97, output);
}
current = tree;
}
}
}
}
return;
}
void invertCodes(int codeTable[], int codeTable2[]){
int i, n, copy;
for (i=0; i<27; i++){
n = codeTable[i];
copy = 0;
while(n>0){
copy = copy * 10 + n%10;
n /= 10;
}
codeTable2[i] = copy;
}
return;
}
int main(){
Node *tree;
int codeTable[27], codeTable2[27];
int compress;
char filename[20];
FILE *input, *output;
buildHuffmanTree(&tree);
fillTable(codeTable, tree, 0);
invertCodes(codeTable, codeTable2);
printf("Type the name of the file\n");
scanf("%s", filename);
printf("1 to compress, 2 to decompress\n");
scanf("%d", &compress);
input = fopen(filename, "r");
output = fopen("output.txt", "w");
if(compress == 1){
compressFile(input, output, codeTable2);
}else{
decompressFile(input, output, tree);
}
return 0;
}