Reputation: 243
I have a problem, when I use this on a 41 kb file it compressed (Although because it uses run-length encoding it always seems to double the size of the file) and decompresses properly. However when I tried to use it on a 16,173 kb file and I decompressed it, it didn't open and the file size was 16,171 kb....so it decompressed it but it didn't return back to it's original form....something screwed up....Has me baffled, I just can't seem to figure out what I am doing wrong....
The method used is run-length encoding, it replaces every byte with a count followed by the byte.
Before:
46 6F 6F 20 62 61 72 21 21 21 20 20 20 20 20
After:
01 46 02 6F 01 20 01 62 01 61 01 72 03 21 05 20
Here is my code:
void compress_file(FILE *fp_in, FILE *fp_out)
{
int count, ch, ch2;
ch = getc(fp_in);
for (count = 0; ch2 != EOF; count = 0) {
// if next byte is the same increase count and test again
do {
count++; // set binary count
ch2 = getc(fp_in); // set next variable for comparison
} while (ch2 != EOF && ch2 == ch);
// write bytes into new file
putc(count, fp_out);
putc(ch, fp_out);
ch = ch2;
}
fclose(fp_in);
fclose(fp_out);
fprintf(stderr, "File Compressed\n");
}
void uncompress_file(FILE *fp_in, FILE *fp_out)
{
int count, ch, ch2;
for (count = 0; ch2 != EOF; count = 0) {
ch = getc(fp_in); // grab first byte
ch2 = getc(fp_in); // grab second byte
// write the bytes
do {
putc(ch2, fp_out);
count++;
} while (count < ch);
}
fclose(fp_in);
fclose(fp_out);
fprintf(stderr, "File Decompressed\n");
}
Upvotes: 0
Views: 1761
Reputation: 243
Here is the working source code:
// Chapter 22 Programming Project #7
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void compress_file(FILE *fp_in, FILE *fp_out);
void uncompress_file(FILE *fp_in, FILE *fp_out);
int main(void)
{
FILE *fp_in, *fp_out;
char nm_in[FILENAME_MAX], nm_out[FILENAME_MAX];
int chk;
for (;;) {
printf(" ----------------------------------------- \n");
printf("| 1 - Compress |\n");
printf("| 2 - Decompress |\n");
printf("| 3 - Exit |\n");
printf(" ----------------------------------------- \n");
do {
printf("Enter a command: ");
scanf(" %d", &chk);
} while (isalpha(chk));
if (chk == 3)
exit(EXIT_SUCCESS);
printf("Enter input file name: ");
scanf(" %s", nm_in);
printf("Enter output file name: ");
scanf(" %s", nm_out);
// Open file to read from
while ((fp_in = fopen(nm_in, "rb")) == NULL) {
fprintf(stderr, "Can't open \"%s\"\n", nm_in);
printf("Enter input file name: ");
scanf(" %s", nm_in);
}
// Open file to write to
while ((fp_out = fopen(nm_out, "wb")) == NULL) {
fprintf(stderr, "Can't create \"%s\"\n", nm_out);
printf("Enter output file name: ");
scanf(" %s", nm_out);
}
switch(chk) {
case 1: compress_file(fp_in, fp_out); break;
case 2: uncompress_file(fp_in, fp_out); break;
}
putchar('\n');
}
return 0;
}
void compress_file(FILE *fp_in, FILE *fp_out)
{
int count, ch, ch2, chk;
ch = getc(fp_in);
ch2 = ch;
while (ch2 != EOF) {
// if next byte is the same increase count and test
for (count = 0; ch2 == ch && count < 255; count++) {
ch2 = getc(fp_in); // set next variable for comparison
}
// write bytes into new file
putc(count, fp_out);
putc(ch, fp_out);
ch = ch2;
}
fclose(fp_in);
fclose(fp_out);
fprintf(stderr, "File Compressed\n");
}
void uncompress_file(FILE *fp_in, FILE *fp_out)
{
int count, ch, ch2;
for (count = 0; ch2 != EOF; count = 0) {
ch = getc(fp_in); // grab first byte
ch2 = getc(fp_in); // grab second byte
// write the bytes
do {
putc(ch2, fp_out);
count++;
} while (count < ch);
}
fclose(fp_in);
fclose(fp_out);
fprintf(stderr, "File Decompressed\n");
}
Upvotes: 1
Reputation: 3335
You miss to check your run length count for char overflow, so this will go wrong if you have more than 255 identical characters in your file in sequence.
Upvotes: 6