The program for recover I made make all 50 jpg(s) perfectly. I have checked them individually and they are perfect.

The code is...

FILE* infile = fopen("card.raw", "r");

// detect the first jpeg
char jpeg0[4] = {0xff, 0xd8, 0xff, 0xe0};
char jpeg1[4] = {0xff, 0xd8, 0xff, 0xe1};
char firstchk[4];

fread(firstchk, 1, 4, infile);
while((memcmp(firstchk, jpeg0, 4) || 
    memcmp(firstchk, jpeg1, 4)) && firstchk[3] != EOF)
    fseek(infile, -3, SEEK_CUR);
    fread(firstchk, 1, 4, infile);
fseek(infile, -1, SEEK_CUR);

// open new jpeg
char buffer[512];

fread(buffer, 1, 512, infile);

int filecount = 0;
int flag = 0;
FILE* outfile;
    // write 512 bytes until a new jpeg is detected
    if ((buffer[0] == jpeg0[0] && buffer[1] == jpeg0[1] && 
    buffer[2] == jpeg0[2] && buffer[3] == jpeg0[3]) || 
    (buffer[0] == jpeg1[0] && buffer[1] == jpeg1[1] && 
    buffer[2] == jpeg1[2] && buffer[3] == jpeg1[3]))
        if (flag == 0)
            flag = 1;

        char fname[8];
        sprintf(fname, "%03d.jpg", filecount);
        outfile = fopen(fname, "w");

    fwrite(buffer, 1, 512, outfile);
    // find end of file
}while(fread(buffer, 1, 512, infile) == 512);


return 0;

When I run 'check50' the following error is given:

enter image description here


I don't understand how you are able to run the code locally. The code is failing because it is generating a segmentation fault with the first if statement in the main do/while loop - both at the check50 servers and on my system. Have you made any changes to the .h file or the makefile? Is your IDE up to date with update50? Are you running in a different environment?

Rather than debug that, I'm going to let you have a shot at it, along with a suggestion for redesign. If you reread the pset specification, it says that a signature will appear as the FIRST 4 bytes of a 512 byte block. Your code tests every byte from the beginning of the data until the first signature is found. Consider that random data could match a signature in the middle of a 512 byte block. Your code would find it and would report a false positive for a signature. From there on, all of the results would be garbage. This also takes a lot of time, so if it did compile, it could potentially time out.

Since you don't have to check every byte before the first signature, most of the code before the do/while loop could be removed, streamlining the process.

Next, using a char type for your buffers, which is actually a signed char, can present problems. As mentioned in lecture, an unsigned one byte type is better. It will hold data without modifying it or applying 2's complement logic (that's how negative numbers are handled, remember?). Look into unsigned char or uint8_t. You could use these to declare a BYTE type, as was done in resize.

Speaking of streamlining, take a look at your if conditions. It's basically "4 compares for signature A or 4 compares for string B". You need to think about efficient programming whenever writing code. In this case, instead of 8 different comparisons, you could write this as 5. Since the first three bytes are the same in both signatures, you could write

(   buffer[0] == jpeg0[0] && buffer[1] == jpeg0[1] && buffer[2] == jpeg0[2] 
&& (buffer[3] == jpeg0[3] || buffer[3] == jpeg1[3])   )

But there's still a problem. The spec says that the 4th byte can be anything from 0xE0 to 0xEF, so a change is in order.

There may well be other problems, but this should give you quite a lot to think about. Depending on how you recode, problems may go away and new ones appear. If you still have trouble, you should consider a new question with the revised code.

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

  • I am using online ide of cs50 at cloud9 and it's updated. I don't know why the program does not run on your's. I made the changes you mentioned but they were not what I desired. Nov 7 '16 at 4:24
  • I came across an observation when I tried checking only the first file, I deleted my code for recovering other files and then check50 expected last file to be 015.jpg while I was able to recover 50 files. I don't know why but looks like I am expected to recover different files. Nov 7 '16 at 4:58
  • That's a good observation. Maybe check50 is using different input data for testing. ;-)
    – Cliff B
    Nov 7 '16 at 5:01
  • How many images did your's recover? Nov 7 '16 at 5:03
  • I'll just say that my code recovered the correct number of files no matter which input file was used.
    – Cliff B
    Nov 7 '16 at 5:10

You must log in to answer this question.

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