I cannot figure out where in heck I've gone wrong with this program. It outputs 50 files, numbered correctly and with different sizes. However, they are all blank.

When I run "head -q -c4 *.jpg | xxd -g 1 -c 4" in the command line it shows all files as starting with "ff d8 ff e0". Your help is appreciated!

 * recover.c
 * Computer Science 50
 * Problem Set 4
 * Recovers JPEGs from a forensic image.

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

//1. Open memory card file. DONE
//2. Find begining of jpg
//3. Open a new jpg
//4. Write 512 bytes until new jpg is found
//5. Detect end of file

int main(void)
    //Open memory card file.
    FILE* memoryCard = fopen("card.raw", "r");
    if (memoryCard == NULL)
        printf("Card card.raw could not open!");
        return 0;

    uint8_t buffer[512] = {0};
    uint8_t jpeg[5] = {0xff, 0xd8, 0xff, 0xe0, 0xe1};

    //how many chars my filename will hold
    char filename[8];

    //create a temp img file
    FILE* img = NULL; 

    //int counter for jpg file names
    int counter = 0;

    //Detects end of file and end program
   while(fread(buffer, 512, 1, memoryCard))
        //Find beginning of jpg 
        //0xff 0xd8 0xff 0xe[0 or 1]-> First 4 bytes in a jpg
        //1111-1111, 1101-1000, 1111-1111, 1110 
        if (buffer[0] == jpeg[0] && buffer[1] == jpeg[1] && buffer[2] == jpeg[2] && (buffer[3] == jpeg[3] || buffer[3] == jpeg[4]))
            if (img != NULL)

            //name new file and open it
            sprintf(filename, "%03d.jpg", counter);
            img = fopen(filename, "a");

            //Write 512 bytes until new jpg is found 
            fwrite(buffer, 512, 1, img);

            counter = counter + 1;

Your program is doing a good job (although not perfect) of detecting the blocks with the signature, creating the files and writing out the first block of each file. However, you have done nothing to process the subsequent blocks in each image file, which will NOT have the signature. In other words, you detect a signature block, create a file and write out the first block, but then skip all of the remaining blocks in the file.

Regarding the 'not perfect' comment, it appears that you're working off of last year's directions which will have two different signatures to search for, with the 4th byte different. The 2016 pset says the following: The fourth byte, meanwhile, is either 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, of 0xef. Put another way, the fourth byte’s first four bits are 1110. http://cdn.cs50.net/2016/x/psets/4/pset4/pset4.html#recover

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

  • Thanks Cliff! I got it all sorted out, that was a great way you lead me to the solution there without giving it away. – Timothy Chasteen Jan 27 '16 at 5:46
  • Also thanks for answering so soon, this would have driven me nuts if I had to stare at it for a minute longer! – Timothy Chasteen Jan 27 '16 at 5:47

You must log in to answer this question.

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