2016-12-04 6 views
0

Я пишу программу для сжатия файла, состоящего из шестнадцатеричных значений, в код длины строки. Например, данный файл:программа для сжатия кода длины файла в C

46 6f 6f 20 62 61 72 21 21 21 20 20 20 20 20 

мой код должен произвести следующий файл:

01 46 02 6f 01 20 01 62 01 61 01 72 03 21 05 20 

Я не знаю, почему программа, которую я написал застревает. Любая помощь будет оценена по достоинству.

#include <stdio.h> 
#include <stdlib.h> 

#define TRUE 1 
#define FALSE 0 

int main(void){ 
    int a, b, c, count=1, flag=TRUE; 

    FILE *file; 
    FILE *out; 

    file = fopen("input.txt", "r"); 

    if(file){ 
     out = fopen("input.txt.out", "a"); 
     fscanf(file, "%x", &a); 
     while(fscanf(file, "%x", &c)){ 
      while(flag==TRUE){ 
       if(c==a){ 
        count= count+1; 
       }else{ 
        flag = FALSE; 
       } 
       b=a; 
       a=c; 
      } 
      fprintf(out, "%d %02x ", count, b); 
      count = 1; 
      flag = TRUE; 
     } 
    }else{ 
     printf("ERROR: file not found."); 
    } 
} 

EDIT: Я обновил код с удалением feof (файл) аргумент и заменив его реальной функции ввода/вывода, а!. Спасибо за понимание. Однако моя программа все еще не работает.

+1

Как можно более крупный выход считать «сжатием»? –

+1

[while (! Feof (fp)) всегда неверен] (https://stackoverflow.com/questions/5431941) – user3386109

+1

В большинстве случаев это не отличный способ сжатия; он работает только хорошо, если есть длинные части ввода, которые повторяются. Если повторения нет, файл фактически удваивается по размеру. Если входной сигнал: 6f 6f 6f 6f 6f 6f 01 01 01 01 Выход 06 6f 04 01 , который уменьшает файл до 40% от его первоначального размера. Эффективность зависит от ввода. –

ответ

1

Я не знаю, почему ваша программа «застревает», но это может работать лучше. Заметьте, я сбросил бессмысленные a, b, c и правду.

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    int lastchar, thischar, count; 

    FILE *finp; 
    FILE *fout; 
    finp = fopen("input.txt", "r"); 
    fout = fopen("output.txt", "w");    // changed "a" to "w" 
    if(fout == NULL || finp == NULL) { 
     puts("Error opening file(s)"); 
     exit(1); 
    } 

    count = 1; 
    fscanf(finp, "%x", &lastchar); 

    while(fscanf(finp, "%x", &thischar) == 1) {  // func value better then feof 
     if(thischar == lastchar) { 
      count++; 
     } 
     else { 
      fprintf(fout, "%02X %02X ", count, lastchar); 
      count = 1; 
     } 
     lastchar = thischar; 
    } 
    fprintf(fout, "%02X %02X ", count, lastchar); // discharge remaining 

    fclose(fout); 
    fclose(finp); 
    return 0; 
} 
 
Program input: 46 6f 6f 20 62 61 72 21 21 21 20 20 20 20 20 

Program output: 01 46 02 6F 01 20 01 62 01 61 01 72 03 21 05 20 

Лучший способ реализации RLE является выбор «Escape» значение, чтобы определить, когда сжатие следующим образом. Таким образом, 3 значения будут кодировать последовательность сжатия, и поэтому стоит только сжимать 3 или более одинаковых. Все остальные символы являются дословными, за исключением самого escape-символа.