I am writing a program to compress a file consisting of hexadecimal values into run-length code. For example, given a file:
46 6f 6f 20 62 61 72 21 21 21 20 20 20 20 20
my code should produce the following file:
01 46 02 6f 01 20 01 62 01 61 01 72 03 21 05 20
I don't know why the program I've written gets stuck. Any help would be appreciated.
#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: I updated the code removing the !feof(file) argument and replacing it with an actual I/O function instead. Thanks for the insight. However, my program still doesn't work.
I don't know why your program "gets stuck" but this might work better. Note I have dumped the meaningless a, b, c
and the truth stuff.
#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
A better way of implementing RLE is to choose an "escape" value to define when a compression follows. Thus 3 values will encode a compression sequence, and so it is only worth compressing 3 or more the same. All other characters are verbatim, except the escape character itself.