0

This is my code for recover.c in pset4:

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

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Enter only one filename.\n");
        return 1;
    }

    char *filename = malloc(8);
    FILE *img;
    FILE *card = fopen(argv[1], "r");
    uint8_t buffer[512];
    int counter = 0;
    int open = 0;
    int read;

    while ((read = fread(&buffer, 1, 512, card)) != 0)
    {
        if (((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) &&
             (buffer[3] >= 0xe0) && (buffer[3] <= 0xef)))
        {
            if (open == 1)
                fclose(img);
            sprintf(filename, "%03i.jpg", counter);
            img = fopen(filename, "w");
            fwrite(&buffer, 1, 512, img);
            counter++;
            open = 1;
        }
        else if (open && (read == 512))
        {
            fwrite(&buffer, 1, 512, img);
        }
/*       else if (read < 512)
        {
           fclose(img);
           open = 0;
        }*/
    }
    free(filename);
    fclose(img);
    fclose(card);
    return 0;
}

After debugging and a little trial and error, I realized that fread() does not return any value less than 512 at all. The control didn't enter the last else if statement which is now a comment. This is confusing because I supposed that fread() would return less than 512 in a block with slack space and the walkthrough video for recover.c also implies that. Is there a problem with my code or did I misunderstand the functionality of the fread() function?

1 Answer 1

0

I think you're looking for a problem where none exists. ;-)

fread() returns the total number of elements successfully read. This maps to the third parameter in the call. Ideally, it will be the same number. If fewer elements are read, then it can go as low as zero. It should never be greater than the number of elements to be read.

Add to that, the source file size is an exact multiple of 512 bytes. That means that the fread statement will return 512 except for the last read attempt. At that point, there's nothing to read, so it returns 0 and the loop terminates.

To test this, you could try uncommenting the code and changing the 512 in the fread to 500 and see what happens when the last bit of data is read. The output files won't be right, but it'll show what happens when there's an odd block at the end. (You'll have to adjust the code to deal with an added seg fault if you do though.) Better still, you could make a copy of the input file and trim a few bytes off the end of it to see what happens.

This code is much better than the code from your last question. Well done.

1
  • Thank you for the detailed explanation and the helpful suggestions; I appreciate your guidance! Commented May 14 at 9:39

You must log in to answer this question.

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