为什么在这个循环中 open return null? C

Why does open return null in this loop? C

我正在研究哈佛 cs50x 的 pset4 恢复,但由于 open 不断返回 NULL,我被卡住了。

// Read each 512 bytes until end of file is reached
FILE* img = NULL;

while (fread(&data, 512, 1, diskptr) == 1)
{
    // Check for jpeg start
    if (checkStart(data, jStart, jStartOE) == true)
    {
        jFound++;
        if (jFound == 1)
        {
            printf("newfound\n");
            // Name and open the first jpeg file
            char title[12];
            sprintf(title, "%03d.jpg", jFound - 1);
            FILE* img = fopen(title, "w");
            fwrite(&data, 512, 1, img);
        }
        else if (img != NULL)
        {
            printf("closed\n");
            // Close old file
            fclose(img);

            // Open new file
            char title[12];
            sprintf(title, "%03d.jpg", jFound - 1);
            FILE* img = fopen(title, "w");
            fwrite(&data, 512, 1, img);
        } 
    }
    else if (jFound > 0 && img != NULL)
    {
        printf("written\n");
        fwrite(&data, 512, 1, img);
    }
}

我添加了那些 printfs 以查看是否曾经执行过这些 else if 块,当我 运行 它新发现打印一次,然后没有其他打印。由于某种原因,open 返回 NULL,而其他代码块从未执行。

对于某些上下文: 该程序的目的是从 .raw 文件中恢复已删除的 jpeg。 checkStart 只是我创建的一个简单函数,用于确定 512 字节块的前四个字节是否包含 jpeg 签名值。如果他们这样做 returns true 表示当前块是新 jpeg 的开始,如果他们不这样做 returns false。 jFound 只是一个变量,我用它来跟踪程序找到了多少 jpeg,以便它可以正确命名它们并在已经找到第一个 jpeg 时写入。

这一行:

FILE* img = fopen(title, "w");

在以

开头的代码块范围内声明变量'img'
if( iFound == 1 ) and if( img != NULL ) 

每个代码块中的变量'img'是不同的。

这些声明掩盖了已发布代码顶部的声明。

建议

img = fopen(title, "w");

(因此不声明新的 'img' 变量)

这个问题出现在发布的代码中的两个地方。

我还为调用 fopen() 添加了一些错误检查

我还去掉了逻辑中的卷积

但是,当任何其他文件也在磁盘的同一区域中时,代码不会总是捕捉到实际 .jpg 文件的末尾。

如果有任何文件段被覆盖,代码将不会捕捉到这一事实。

I.E.该代码可能无法正确提取 .jpg 文件,并且写入提取的文件副本可能会导致覆盖您要提取的已删除文件的部分内容。 IE。将新文件放在不同的磁盘上

FILE* img = NULL;

while (fread(&data, 512, 1, diskptr) == 1)
{
    // Check for jpeg start
    if (checkStart(data, jStart, jStartOE))
    {

        if (img != NULL)
        {
            printf("closed\n");
            // Close old file
            fclose(img);
        }

        // Open new file
        char title[12];
        sprintf(title, "%03d.jpg", jFound - 1);

        if( NULL == (img = fopen(title, "w") ) )
        { // then fopen failed
            perror( "fopen for output file failed");
            exit( EXIT_FAILURE );
        }

        // implied else, fopen successful

        fwrite(&data, 512, 1, img);
    }

    else if (img != NULL)
    {
        printf("written\n");
        fwrite(&data, 512, 1, img);
    }
}