1

I'm not sure if check50 is working correctly? When i run my code, i recover all 50 jpg and i can view them. This is what i get when i run check50 2016.recover recover.c

:) recover.c exists

:) recover.c compiles

:) handles lack of forensic image

:) recovers 000.jpg correctly

:) recovers middle files correctly

:( recovers last file correctly

https://sandbox.cs50.net/checks/0e458fffc22f415aac1db80f2b7fd8a7

To make sure i did not miss a jpg, i change by test to not end until 050.jpg was found, instead of ending when fread returns a block smaller then 512 bytes. I was expecting a segmentation fault, or to find the missing image. What happen it that the last jpg 049.jpg got very big, a few megabytes big, and was not readable, but it never found a fifty first image. So i am sure it only 50 in the recover file.

So i am confused why check50 is telling me that :( recovers last file correctly.

This is the code i wrote.

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

#define BLOCK 512

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover <disk name>\n");
        return 1;
    }

    // remember filenames
    char *infile = argv[1];

    // open input file 
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    unsigned char buffer[BLOCK]; // storage for block from memory card.
    int flag;
    char filename[15];
    int i=0;
    FILE *img;

    do {
        flag = fread(buffer, sizeof(buffer), 1, inptr);
        if ((buffer[0] == 0xff) && 
            (buffer[1] == 0xd8) && 
            (buffer[2] == 0xff) && 
            ((buffer[3] & 0xf0) == 0xe0))
            {
            if(i>0)
                fclose(img);

            //creat new jpeg
            sprintf(filename, "%03d.jpg", i); 
            i++;
            img = fopen(filename, "w");
            fwrite(buffer, sizeof(buffer), 1, img);
            }
        else if (i == 0)
            continue;
        else
            fwrite(buffer, sizeof(buffer), 1, img);
    } while(flag == 1);

    if(i)
    {
    fclose(img);
    fclose(inptr);
    }
    return 0;
}
4

Yes, you're getting 50 files, but the last file is wrong. While the image looks right, it has a problem. It's 512 bytes too large.

This is a fairly common error. Look closely at what the code does at the end of the input file. It will try to do one last read of the input file and will hit the EOF condition, since there's no data to read. The buffer will not be overwritten because the read failed. It will then execute the write to the output file, which still contains the previous 512 bytes, since it wasn't overwritten. Finally, the exit conditions for the while loop are triggered, but the damage is already done.

You need to alter the code so that this extra write doesn't occur.

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

4
  • Will not be able to work on the code until Tuesday or Wednesday of next week because I'm going to be very busy with work. I'll accept it once I get it working. Thank you. – Manny_Mar Feb 23 '17 at 17:41
  • It worked, I just added one more if condition to prevent the program from writing when the flag was not 1. I'm not sure if i should leave this up, since it almost a complete solution to recover, just missing one if statement. – Manny_Mar Feb 25 '17 at 3:15
  • I ran into the same thing and this answer helped me figure out the issue. I think part of the problem is check50 is out of date--it confusingly says "recovers 015.jpg correctly" when I think it means to say "recovers last image correctly", as I'm guessing in prior years there were only 15 images. This should be fixed to not confuse new students :) – Tian Sep 8 '17 at 1:10
  • Or, Tian, they intentionally use a different data set to check the program than the one that's provided. It's yet another hidden lesson that thorough testing is important before releasing a program. Someday, every programmer will have to know how to create their own test data sets as well as being able to deal with unexpected results. At this point in the course, it's time to learn that lesson. ;-) – Cliff B Sep 8 '17 at 1:55

You must log in to answer this question.

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