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

CS50 Recover作业报错“The recovered image does not match”,所有恢复的JPG均为空白白图

CS50 Recover作业报错“The recovered image does not match”,所有恢复的JPG均为空白白图

Hey there! Let's dig into this blank JPG problem you're hitting in the CS50 Recover assignment—this is such a common gotcha when you're first getting your hands dirty with binary file I/O in C, so don't stress too much about it!

First, let's break down why your recovered JPGs might be coming out blank: 9 times out of 10, it's related to how you're reading/writing the binary data, or a missing piece in your block-reading logic. Let's go through the most likely culprits, using your code snippet as a starting point:

1. You're using text mode instead of binary mode for file operations

Looking at your code, you opened the card file with "r":

FILE *card = fopen(argv[1], "r");

That's a big problem! When you use text mode ("r" or "w"), your system will automatically translate newline characters (like \n) to match the OS's line-ending format. But JPGs are binary files—they rely on every single byte being exactly as it is. This translation messes up the binary data, so when you write it out to your JPG files, you're either missing critical bytes or writing garbage that the image viewer can't interpret (hence the blank white screen).

Fix this by using binary mode for all file operations:

  • Open the input card file with "rb" (read binary)
  • Open your output JPG files with "wb" (write binary)

2. You might be missing a 512-byte buffer for reading/writing blocks

The Recover assignment requires reading the memory card in 512-byte chunks—this is non-negotiable, since that's how the data is structured on the card. Looking at your code snippet, I don't see a buffer defined (like uint8_t buffer[512];). Without this buffer, you can't properly read the blocks of data to write to your JPGs. If you're not reading any actual binary data and writing empty blocks, that's a surefire way to get blank files.

3. Your JPG signature detection or write logic might be incomplete

Let's make sure you're handling the JPG start/end correctly:

  • You need to detect the JPG signature: the first four bytes should be 0xff 0xd8 0xff, and the fourth byte should be between 0xe0 and 0xef (you can check this with (buffer[3] & 0xf0) == 0xe0 to mask out the last four bits)
  • When you detect a new JPG signature, you need to close the previous output file (if one was open) before opening a new one
  • You should only start writing data to a file after you've found the first valid JPG signature—before that, you're just skipping over non-JPG data

4. Let's fix up your code with these fixes

Here's a revised version of your code that addresses these issues, with comments explaining each key part:

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

int main(int argc, char *argv[])
{
    // Check for correct number of arguments
    if (argc != 2) {
        printf("Usage: %s image\n", argv[0]);
        return 1;
    }

    // Open input card file in BINARY read mode
    FILE *card = fopen(argv[1], "rb");
    if (card == NULL) {
        printf("Could not open the input file.\n");
        return 1;
    }

    // Allocate memory for filename (8 bytes is enough for "000.jpg" + null terminator)
    char *filename = malloc(8);
    if (filename == NULL) {
        fclose(card);
        printf("Memory allocation failed.\n");
        return 1;
    }

    FILE *img = NULL;
    uint8_t buffer[512]; // Critical: 512-byte buffer to hold each block of data
    int img_count = 0;
    int found_first_jpg = 0;

    // Read 512-byte blocks until we can't read a full block
    while (fread(buffer, sizeof(uint8_t), 512, card) == 512) {
        // Check if we've found the start of a new JPG
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) {
            // If we already have an open JPG file, close it first
            if (img != NULL) {
                fclose(img);
            }
            // Generate the filename (e.g., 000.jpg, 001.jpg)
            sprintf(filename, "%03d.jpg", img_count);
            // Open the new JPG file in BINARY write mode
            img = fopen(filename, "wb");
            img_count++;
            found_first_jpg = 1; // Mark that we've started finding valid JPGs
        }

        // If we've found the first JPG, write the current block to the open file
        if (found_first_jpg) {
            fwrite(buffer, sizeof(uint8_t), 512, img);
        }
    }

    // Clean up: close any remaining open files and free allocated memory
    if (img != NULL) {
        fclose(img);
    }
    fclose(card);
    free(filename);

    return 0;
}

Quick recap of the key fixes

  • Switched to binary file modes (rb/wb) to avoid corrupting binary data
  • Added the required 512-byte buffer for reading/writing blocks
  • Implemented proper JPG signature detection with masking for the fourth byte
  • Ensured we only write data after finding the first valid JPG, and close files when switching to a new JPG
  • Added proper cleanup steps to avoid memory leaks and file handle leaks

Give this revised code a shot, and your JPGs should show up correctly instead of being blank!

备注:内容来源于stack exchange,提问作者nerdkingprime

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 13:28:02