user5183133
user5183133

Reputation:

Why does open return null in this loop? C

I am working on pset4's recover of Harvard's cs50x and I'm stuck because open keeps returning 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);
    }
}

I added those printfs to see if those else if blocks were ever executed and when I run it newfound prints once and then nothing else prints. For some reason open is returning NULL and the other blocks of code are never executed.

For some context: The aim of this program is to recover deleted jpegs from a .raw file. checkStart is just a simple function that I made that determines if the first four bytes of the 512 bytes block contain the jpeg signature values. If they do it returns true signalling that the current block is the start of a new jpeg and if they don't it returns false. jFound is just a variable that I used to keep track of how many jpegs the program has found so it can name them properly and write if the first jpeg has already been found.

Upvotes: 1

Views: 764

Answers (1)

user3629249
user3629249

Reputation: 16540

this line:

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

declares the variable 'img' inside the scope of the code block started with

if( iFound == 1 ) and if( img != NULL ) 

The variable 'img' is different within each code block.

These declarations mask the declaration at the top of the posted code.

Suggest

img = fopen(title, "w");

(so does not declare a new 'img' variable)

This problem occurs in two places in the posted code.

I also added some error checking for the calls to fopen()

I also removed the convolutions in the logic

however, the code will not always catch the end of the actual .jpg file when any other files are also in the same area of the disk.

And if any of the file segments have been overwritten, the code will not catch that fact.

I.E. the code may fail to properly extract the .jpg file(s) and writing extracted copies of the files may result in overwriting part(s) of the deleted files that you want to extract. I.E. place the new files on a different disk

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);
    }
}

Upvotes: 8

Related Questions