title: Compressing a file in C
body: <p>I dont really know how to shorten the code so I put the whole thing below, but when I run the code and I try to compress it, it keeps on running and when I stop it using ctrl+z the resulting output file is larger than the file I tried to compress. I think the error is from my compress file function, but below is the whole code. It compiles and runs but its not quite what I expect. Also it doesn't print out the statements that I put in my compressFile function.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;math.h&gt;
  
  #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]-&gt;value== -1)
          i++;
      smaller = i;
      if(i == differentFrom){
          i++;
          while(array[i]-&gt;value== -1)
              i++;
          smaller = i;
      }
  
      for(i=1; i&lt;27; i++){
          if(array[i]-&gt;value== -1)
              continue;
          if(i==differentFrom)
              continue;
          if(array[i]-&gt;value&lt;array[smaller]-&gt;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&lt;27; i++){
          array[i] = malloc(sizeof(Node));
          array[i]-&gt;value = engLetterFreq[i];
          array[i]-&gt;letter = i;
          array[i]-&gt;left = NULL;
          array[i]-&gt;right = NULL;
   }
  
      while(subTrees&gt;1){
          smallOne = findSmaller(array, -1);
          smallTwo = findSmaller(array, smallOne);
          temp = array[smallOne];
          array[smallOne] = malloc(sizeof(Node));
          array[smallOne]-&gt;value=temp-&gt;value+array[smallTwo]-&gt;value;
          array[smallOne]-&gt;letter=127;
          array[smallOne]-&gt;left=array[smallTwo];
          array[smallOne]-&gt;right=temp;
          array[smallTwo]-&gt;value = -1;
          subTrees--;
      }
  
      *tree = array[smallOne];
  
      return;
  }
  
  void fillTable(int codeTable[], Node *tree, int Code){
  
      if(tree-&gt;letter&lt;27){
          codeTable[(int)tree-&gt;letter] = Code;
      }else{
          fillTable(codeTable, tree-&gt;left, Code*10+1);
          fillTable(codeTable, tree-&gt;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&gt;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 &lt;&lt; 1;
          }
      }
  
      if(bitsLeft != 8){
          x = x &lt;&lt; (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 &lt;&lt; 7;
      int i;
  
      while ((c=fgetc(input))!=EOF){
  
          for(i=0; i&lt;8; i++){
  
              bit = c &amp; mask;
              c = c &lt;&lt; 1;
  
              if(bit==0){
                  current = current-&gt;left;
                  if(current-&gt;letter != 127){
                      if(current-&gt;letter == 26){
                          fputc(32, output);
                      }else{
                          fputc(current-&gt;letter+97, output);
                      }
  
                      current = tree;
                  }
              }else{
                  current = current-&gt;right;
                  if(current-&gt;letter != 127){
                      if(current-&gt;letter == 26){
                          fputc(32, output);
                      }else{
                          fputc(current-&gt;letter+97, output);
                      }
  
                      current = tree;
                  }
              }
          }
      }
  
      return;
  }
  
  void invertCodes(int codeTable[], int codeTable2[]){
  
      int i, n, copy;
  
      for (i=0; i&lt;27; i++){
  
          n = codeTable[i];
          copy = 0;
  
          while(n&gt;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(&amp;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", &amp;compress);
  
      input = fopen(filename, "r");
      output = fopen("output.txt", "w");
  
      if(compress == 1){
          compressFile(input, output, codeTable2);
      }else{
          decompressFile(input, output, tree);
      }
  
      return 0;
  
  }
  </code></pre>