CS5Ox Pset4 Recover:代码仅恢复部分图像

CS5Ox Pset4 Recover: code only recovers partial images

我有一些 CS50 Pset4 的半工作代码。如果你 运行 它你会看到它恢复了 27 个 jpg 文件,但只有前几行是可见的。

有人能指出我正确的方向吗?

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

typedef uint8_t BYTE;

int main (int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover infile\n");
        return 1;
    }

    // open file to be recovered
    FILE *infile = fopen(argv[1], "r");
    if (infile == NULL)
    {
        fprintf(stderr, "Could not open infile.\n");
        return 2;
    }

    // temp storage for blocks
    BYTE buffer[512];

    // variable to store filename
    char filename[8];

    //store number of recovered files
    int n = 0;

    // temp storage for outfiles
    FILE* outfile = NULL;

    // iterate over all blocks of memory until end of SD card is reached
    while (fread(buffer, 512, 1, infile) != 0)
    {
        // read one block
        fread(buffer, 512, 1, infile);

        // check if block is start of jpeg
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            //close previous file if already open
            if(outfile != NULL)
            {
                fclose(outfile);
            }

            // creeate new outfile
            sprintf(filename, "%03i.jpg", n);
            outfile = fopen(filename, "w");

            // write block to outfile
            fwrite(buffer, 512, 1, outfile);

            n++;
        }
        else
        {
            // write block to current outfile
            if(outfile != NULL)
            {
                fwrite(buffer, 512, 1, outfile);
            }
        }
    }

    //close last outfile
    fclose(outfile);

    //close infile
    fclose(infile);
}

我发现有几件事可能会导致该问题。

首先,检查您的 n 计数器的顺序。应该在您实际开始写入新文件之前添加计数器,但这只是一个偏好问题,以及您希望代码有多干净。

其次,尝试用以下代码替换您的 else 条件:

if(outfile != NULL)                          
      {
        fwrite(buffer, 512, 1, outfile);
}

注意:请记住,我已将您的 else 条件替换为 if 条件。这是因为当满足第一个if条件时,然后执行这个条件和'jumps out of the block'。所以 else 将只执行第一个 if 条件不会执行。 如果您想保留 else 条件,那么您应该嵌套另一个 if ,就像您在代码中所做的那样。

else 替换为 if,无论 jpg 的前 3 个字节的值如何(即,无论它们是 0x00、0xff、 0x00),你会得到一个非常清晰易懂的代码。

最后,也是更重要的一点:为什么要在同一个操作中对同一个文件写入两次?注意 n++ 计数器下方的 fwrite() 函数。真的有必要吗?

换句话说:删除这一行:

// read one block fread(buffer, 512, 1, infile);

另一个错误是,你正在读取你的文件两次,并且在每一步中前进两次,所以你会得到一半的信息。 这就是您获得一半图像(大约 27 张)的原因。

删除这两行:

// read one block fread(buffer, 512, 1, infile);

正如我所说,通过在文件中读写两次,您可以获得一半的信息。这会导致模糊的方式,在这种方式中,您将所有图像都用毫无意义的颜色(我猜)和一半的图像文件着色。

我已经 运行 check50 2016.recover recover.c 使用了您的代码和我刚刚提供给您的固定解决方案,它通过了 CS50 的 check50 的所有检查。花点时间考虑程序中的所有内容,包括控制流(它是其中的重要部分)以及指针的使用。

在没有任何经验的情况下启动 CS50 可能会让人望而生畏。保持。您已经快进入第 5 周了。