CS50 PSET4 恢复:fread() 未填充缓冲区数组

CS50 PSET4 RECOVER: fread() not populating buffer array

您好,感谢您的浏览。

我正在研究 CS50x,并且正在努力 恢复。目的是打开一个 .raw 文件,以 512 字节的块读取其内容,检查 .jpg 的前四个字节 headers,然后将每个 JPEG 数据写入一个新文件。

我编写了 body 代码,文件编译成功。调试器告诉我,我的 buffer[512] 变量仍然是 empty/zeroed。这意味着程序会跳过 if/else 条件并退出。

虽然我在 While 循环中的逻辑可能有缺陷,但我还没有深入到程序中来考虑这一点。

我在发布之前查看了我的问题。有些来源喜欢使用 fread(buffer, 512, 1, input),但 CS50 本身使用 fread(buffer, 1, 512, input)。此外,在初始化文件名​​时,我尝试了 char *filename = malloc(8 * sizeof(char));char filename[8];。对于这两行,我都尝试了每种方法,但仍然缺少一些东西。

我的代码如下。预先感谢您的宝贵时间。

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

typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
    // First check the number of arguments is correct.
    if (argc != 2)
    {
        printf("Correct Usage: ./recover.c [filename]\n");
        return 1;
    }

    // Open the file.
    FILE *inputFile = fopen(argv[1], "r");

    if (inputFile == NULL)
    {
        printf("File not found.\n");
        return 1;
    }

    // Create counter of number of files.
    int counter = 0;
    // Create filename variable
    char *filename = malloc(8 * sizeof(char)); // 7 + 1 for [=10=]
    // Create a 512-size array buffer.
    BYTE buffer[512];
    // Initialise img file for scope access.
    FILE *img = NULL;

    while (fread(buffer, sizeof(BYTE), 512, inputFile))
    {
        // If start of new JPEG:
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            if (counter == 0) // If the FIRST JPEG
            {
                // Make new file:
                sprintf(filename, "%03i.jpg", counter);
                img = fopen(filename, "w");
                fwrite(buffer, sizeof(BYTE), 512, img);
            }
            else // If not the first JPEG
            {
                fclose(img); // Close previous file.
                counter++;
                // Make new file:
                sprintf(filename, "%03i.jpg", counter); // Update filename.
                img = fopen(filename, "w");
                fwrite(buffer, sizeof(BYTE), 512, img);
            }
        }
        else if (counter > 0) // buffer is continuation of previous.
        {
            fwrite(buffer, sizeof(BYTE), 512, img);
        }
        else
        {
            printf("I exited with no images.\n");
            return 2;
        }
    }
    free(filename);
    fclose(img);
    fclose(inputFile);
    return 0;
}

读取原始文件中的第一行后程序退出 (returns)(假设它不是 jpeg header,发行版原始文件就是这种情况)。 else if (counter > 0) 计算结果为 false,因此执行 else 分支。

谢谢大家的回复。问题现已解决!

@DinoCoderSaurus(抱歉,还不能投票)促使我意识到我曾(错误地)假设原始文件中的数据会立即以 .jpeg header 开头(事实上看起来数据以隐藏消息“惊喜”开头)。

Else 条件最初放在那儿是为了避免错误,但当然它会过早地退出 While 循环。几次循环后缓冲区被正确填充。

然后我遇到了第二个问题(@Some_programmer_dude指出)counter++;写错了,也就是说在第一个新的JPEG之后,其他的就写不出来了。

我也会考虑您对最佳做法的意见。