0

I have been working on recover.c in pset4 (2016 edition), and seem to have successfully recovered all 50 photos and named them correctly.

However, when I run it through Check50 with command

check50 2015.fall.pset4.recover recover.c

it returns the following:

:) recover.c exists

:) recover.c compiles

:) recovers 000.jpg correctly

:) recovers middle files correctly

:( recovers last file correctly

All the files were recovered correctly except the last file, even though 049.jpg exists and appears to be intact. I would greatly appreciate if someone could help me find what I am doing wrong in my code. Thank you!

This is my code:

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

typedef uint8_t BYTE;

const int BLOCKSIZE = 512;

int main(void) {
    FILE* cfCard = fopen("card.raw", "r");

    if (cfCard == NULL) {
        printf("Could not open card. \n");
        return 1;
    }

    FILE* outptr = NULL;

    int nameID = 0;

    while (1) {

        BYTE buffer[BLOCKSIZE];

        if (feof(cfCard)) {
            fclose(cfCard);
            if (outptr != NULL) {
                fclose(outptr);
                outptr = NULL;
            }
            return 0;
        }
        fread(buffer, sizeof(BYTE), BLOCKSIZE, cfCard);

        if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) 
            && (buffer[3] >= 0xe0) && (buffer[3] <= 0xef)) {
            if (outptr != NULL) {
                fclose(outptr);
                outptr = NULL;
            }
            char filename[8];
            sprintf(filename, "%03d.jpg", nameID);
            nameID++;
            outptr = fopen(filename, "w");
            if (outptr == NULL) {
                printf("Could not write in file. \n");
                return 1;
            }
            fwrite(buffer, sizeof(BYTE), BLOCKSIZE, outptr);
        } else if (outptr != NULL) {
            fwrite(buffer, sizeof(BYTE), BLOCKSIZE, outptr);
        } 
    }
}
1

This is a very common error. The code reads from the input file, processes data, and then checks for EOF. You have to realize that EOF isn't detected until a read actually hits and tries to read past the end of the file. A read can move the file pointer to the end of the file, but until it actually tries to read the first byte past the end, EOF won't be set.

Usually, the practical result of this error is that an extra block is being written to the output file.

The EOF test has to be incorporated into the read (such as checking the return code from fread) or you have to check for EOF immediately after the read.

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

1
  • Thank you so much for your help! I adjusted my code and now it works.
    – user11799
    Jun 24 '16 at 3:34

You must log in to answer this question.

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