0

I keep ending up with this last error on Check50 - any tips?

    int main(int argc, char *argv[])
    {
    // Check for invalid usage
    if (argc != 2)
    {
        printf("Usage: Recover [file name ...]\n");
        return 1;
    }
// opens the file i.e. memory card
    FILE *file = fopen(argv[1], "r");

// image number for each file created
    int i=0;
    FILE* outptr = NULL; 
    uint8_t block[512];

// If we are not at the end of the file, do the following
    while(!feof(file))
    {

        // read 512 bytes worth i.e. the first block
        fread( block, 512, 1, file);


        // if the first 4 bytes of the block indicate that it is a new JPEG then open a file if a location for the output file doesn't exist
        if ( block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && ((block[3] & 0xf0) == 0xe0) )
        {
            if (outptr != NULL)
            {
                fclose(outptr);
            }

            char filename[8];
            sprintf(filename, "%03i.jpg", i);
            outptr = fopen(filename, "w");
            i++;

            fwrite(block, sizeof(block), 1, outptr);
        }
        else if( i > 0)
        {
            fwrite(block, sizeof(block), 1, outptr);
        }
    }

fwrite(block, sizeof(block), 1, outptr);
fclose(outptr);
fclose(file);

}    

'''

1 Answer 1

1

This is a common mistake. Look at this code and think about exactly what is happening at the end of the input file, or specifically at the last block:

while(!feof(file))
{

    // read 512 bytes worth i.e. the first block
    fread( block, 512, 1, file);

The code tests for EOF, which hasn't been set yet. It reads the last block and processes it, copying it to the output file. Then, it goes back to the top of the while loop and tests for EOF again. Here's the issue. In order to set the EOF flag, the code has to attempt to read past the last byte. It has read the last byte, but nothing more. So, the EOF flag is not set.

Now, the code continues, and tries to read another block. The read fails, so the buffer remains unchanged. Next, the code writes the last valid block, still in the buffer, to the output file again. The result is that the last output file is 512 bytes too large.

But now, the EOF flag is set. When the code returns to the top of the while loop, the test fails and the loop terminates.

I suggest that you read the man page for fread, particularly the return values and think about how you can use that.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .