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

编程作业中JPG照片恢复代码生成不完整文件问题求助

问题分析与修复方案

首先,你的代码核心问题是只在检测到JPG文件头时写入一个数据块,之后就立刻关闭输出文件,完全没有处理该JPG后续的512字节数据块——这就是为什么生成的照片都是不完整的。我们来一步步拆解问题并修复:

核心逻辑错误解析

一个完整的JPG文件由多个连续的512字节块组成,直到下一个JPG头出现(或者文件结束)。你当前的逻辑只处理了每个JPG的第一个块,后续属于该JPG的块都被忽略了,自然生成的文件都是残缺的。

具体修改点与修复后的代码

1. 调整文件读写逻辑

  • 当检测到新JPG头时,先关闭之前打开的输出文件(如果有的话),再创建新文件并保持打开状态
  • 未检测到新头但已有打开的输出文件时,直接将当前块写入该文件(因为这属于当前JPG的内容)
  • 将文件打开模式从"a"改为"w",避免同名旧文件的内容干扰新文件

2. 资源泄漏修复

  • 记得free之前malloc分配的filename内存
  • 程序结束前检查并关闭最后一个可能仍打开的输出文件

修复后的完整代码

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

typedef uint8_t BYTE;

int main(int argc, char *argv[]) {
    if(argc != 2) {
        printf("Usage: ./recover IMAGE\n");
        return 1;
    }

    FILE* memorycard = fopen(argv[1], "r");
    if(memorycard == NULL) {
        printf("Could not open %s.", argv[1]);
        return 1;
    }

    FILE* out = NULL;
    int img_counter = 0;
    BYTE img[512];
    char* filename = malloc(9 * sizeof(char)); // 足够存储"000.jpg" + 字符串终止符

    while (fread(img, 512, 1, memorycard) == 1) {
        // 检测JPG文件头特征
        if(img[0] == 0xFF && img[1] == 0xD8 && img[2] == 0xFF && (img[3] & 0xF0) == 0xE0) {
            // 关闭之前打开的输出文件(如果存在)
            if(out != NULL) {
                fclose(out);
            }
            // 生成新文件名并创建文件
            sprintf(filename, "%03i.jpg", img_counter++);
            out = fopen(filename, "w");
            if(out == NULL) {
                printf("Could not create %s.", filename);
                fclose(memorycard);
                free(filename);
                return 1;
            }
            // 写入当前JPG的第一个块
            fwrite(img, 512, 1, out);
        } else {
            // 如果已有打开的文件,说明当前块属于该JPG,直接写入
            if(out != NULL) {
                fwrite(img, 512, 1, out);
            }
        }
    }

    // 清理所有打开的文件与分配的内存
    if(out != NULL) {
        fclose(out);
    }
    fclose(memorycard);
    free(filename);

    return 0;
}

额外优化说明

  • 把typedef uint8_t BYTE;移到main函数外,更符合C语言的编码习惯
  • 增加了fopen失败的检查逻辑,避免空指针操作导致程序崩溃
  • 确保所有文件资源和动态分配的内存都被正确释放,避免资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:12:42