【问题标题】:C- Run-length encoding doesn't work on large file, worked on smaller fileC-运行长度编码不适用于大文件,适用于较小的文件
【发布时间】:2014-06-18 09:45:10
【问题描述】:

我有一个问题,当我在一个 41 kb 的文件上使用它时,它会被压缩(尽管因为它使用运行长度编码,它似乎总是使文件大小加倍)并正确解压缩。但是,当我尝试在一个 16,173 kb 的文件上使用它并解压缩它时,它没有打开,文件大小为 16,171 kb ......所以它解压缩了它,但它没有恢复到原来的形式.. ..有些事情搞砸了....让我感到困惑,我似乎无法弄清楚我做错了什么....

使用的方法是游程编码,它将每个字节替换为一个计数后跟字节。

之前:

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

这是我的代码:

    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");
    }

【问题讨论】:

  • 您的for 循环测试ch2 != EOF,但ch2 尚未初始化,导致未定义的行为。
  • 除了未初始化的数据,all 文件是否以 binary 模式打开?另外,打印count 在压缩循环的每次迭代中,ch 的值在扩展外循环的每次迭代中再次出现。如果它们不一样,你就发现了你的问题。
  • 运行长度编码仅在相同字节(或字或双字)值的较长序列可以缩短为计数和值时才有用。 RLE 处理每个字节没有意义。
  • 是的,我用二进制打开了两个文件,并在十六进制编辑器中打开了两个文件,一切似乎都检查过了,我想@mfro 搞定了,让我看看我能不能修复它
  • 感谢@user694733,从裂缝中溜走了

标签: c binary run-length-encoding


【解决方案1】:

你错过了检查你的运行长度计数是否有字符溢出,所以如果你的文件中有超过 255 个相同的字符,这就会出错。

【讨论】:

  • 谢谢,我明白你的意思了,这可能是问题
  • 说最好的方法是什么,我是否应该让它重复 255 次计数直到计数结束,或者如果是这样,当我遇到时我应该如何知道在哪里停止计数它...或者我应该添加第二组字节,一个告诉我有多少个 count 字节,另一个告诉我要重复多少个字节?
  • 就像当我阅读文件时,我应该如何知道下一组 FF 是字节还是计数,如果不是,我应该如何判断这不是下一个计数跨度>
  • 涂料! XD 我觉得太愚蠢了哈哈哈,我才明白你的意思....好吧,如果计数超过 255,我明白了...比如说 265,字节是 00,那么我会写 FF 00 10 00 XD 我不知道不知道我是怎么错过的
  • @JohnConner 你能做这个吗?我试了代码,输入的和你想要的完全不一样
【解决方案2】:

这里是工作源代码:

    // 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");
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2018-02-28
    相关资源
    最近更新 更多