You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C90环境下RLE压缩逻辑修正及解压缩实现技术问询

解决你的C90 RLE压缩问题及解压缩实现思路

首先,咱们先搞清楚为什么你的压缩结果不对——你现在的代码是统计每个字符在整个文件里的总出现次数,而不是统计连续重复的字符段。这就是为什么输入AAAAAA333333FFFFF22222时,你得到的是2536A6F5,而正确结果应该是6A635F52。接下来咱们先修正压缩代码里的问题,再聊聊解压缩的实现思路。

1. 压缩代码的错误修正

核心逻辑问题

你的count[256]数组统计的是每个字符的全局出现次数,但RLE算法要求的是连续重复的字符计数。比如你的输入包含4个连续段:6个A、6个3、5个F、5个2,而不是把所有A的数量、所有3的数量按ASCII顺序输出。

循环与if条件的修正

你当前的while循环有个致命bug:

while((n=fgetc(fp))) {
 if(n == EOF) {
 break;
 } else count[n]+=1;
}
  • 循环条件while((n=fgetc(fp)))会在读取到ASCII值为0的字符时提前退出(因为0在C里被视为false)。
  • 你在进入循环后才判断是否为EOF,这种写法既低效又容易出错。

下面是重写后的压缩逻辑,专门跟踪连续重复的字符段:

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

int main(void) {
    FILE *fp = fopen("test.txt", "r");
    FILE *fptr = fopen("compressed_test.txt", "w");
    
    if (fp == NULL) {
        printf("错误:输入文件不存在\n");
        printf("没有可压缩的内容\n");
        exit(EXIT_FAILURE);
    }

    int current_char = fgetc(fp);
    if (current_char == EOF) {
        // 空文件,直接退出
        fclose(fp);
        fclose(fptr);
        return 0;
    }

    int run_count = 1;
    int next_char;

    while ((next_char = fgetc(fp)) != EOF) {
        if (next_char == current_char) {
            // 字符相同,增加连续计数
            run_count++;
        } else {
            // 字符不同:写入当前连续段的结果
            fprintf(fptr, "%d%c", run_count, current_char);
            // 重置为下一个连续段的初始状态
            current_char = next_char;
            run_count = 1;
        }
    }

    // 循环结束后,别忘了写入最后一个连续段
    fprintf(fptr, "%d%c", run_count, current_char);
    printf("压缩完成\n");

    fclose(fp);
    fclose(fptr);
    return 0;
}

重点修正点:

  • 用current_char和run_count跟踪当前连续重复的字符及其次数,替代全局计数的数组。
  • while循环直接用next_char != EOF作为条件,确保只处理有效字符。
  • 循环结束后处理最后一个连续段(因为循环在遇到EOF时终止,最后一段还没写入文件)。

2. RLE解压缩(解码)的实现思路

解压缩的逻辑是反过来的:读取压缩文件中的“数字+字符”对,然后将字符重复对应数字的次数输出即可。具体步骤如下:

  • 打开压缩文件和输出文件。
  • 循环读取文件内容:
    1. 先读取数字部分(如果你的压缩只处理单数字计数(比如最多9个连续字符),直接读一个数字字符转成整数即可;如果要支持多位数,fscanf的%d格式会自动读取连续的数字字符)。
    2. 读取对应的字符。
    3. 将该字符重复数字次数写入输出文件。
  • 处理完所有内容后关闭文件。

举个简单的解压缩示例代码框架:

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

int main(void) {
    FILE *compressed_fp = fopen("compressed_test.txt", "r");
    FILE *decompressed_fp = fopen("decompressed_test.txt", "w");
    
    if (compressed_fp == NULL) {
        printf("错误:压缩文件不存在\n");
        exit(EXIT_FAILURE);
    }

    int count;
    char c;

    while (fscanf(compressed_fp, "%d%c", &count, &c) == 2) {
        // 重复count次写入字符c
        for (int i = 0; i < count; i++) {
            fputc(c, decompressed_fp);
        }
    }

    printf("解压缩完成\n");
    fclose(compressed_fp);
    fclose(decompressed_fp);
    return 0;
}

注意:如果遇到压缩文件损坏等格式异常情况,还可以添加额外的错误判断逻辑,比如检查读取的数字是否为正整数等。

内容的提问来源于stack exchange,提问作者Albert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:36:19