I'm sorry for being vague, but I don't know up from down where recover's concerned. I'm trying to stick to the pseudo code and believe I've reached the point where I want to test if a jpg's already been found, but:

  1. I don't believe my code is structured correctly. Rather than skip over the leading 512 blocks, I expect my code tries to write them because I use else. Makes you think I could fix it, but if I don't close the if loop, it doesn't go back to get the next 512 block, which makes me question whether the while loop is badly done. I don't know if it could work because there's no file open it can write to until the if condition evaluates to true.
  2. I was surprised I had to move the file ptr for the jpgs outside of the while loop to resolve an error. I believe it was because the else loop couldn't see it, but I'd love to be certain and learn a better way.

  3. I used EOF in my while loop because of an example in the shorts for week 4 and therefore thought it was an ok practice, but in searching stack exchange I've stumbled on posts re: EOF not working well in while loops which were beyond me, but made me question whether it's a mistake.

  4. To test whether a jpg's already been found meant if condition to me. I don't know how to code it. I've written "if jpgcount was incremented," but can't see how "if (jpgcount = jpgcount + 1)" can work. Even tried defining one in terms of the total number of jpgs.

    #include <stdio.h>
    #include <stdint.h>
    typedef uint8_t  BYTE;
    int main(int argc, char *argv[])
        // program accepts 1 CLA
        if (argc != 2)
            fprintf(stderr, "Usage: ./recover image");
            return 1;
        // open image file
        FILE *image_ptr = fopen(argv[1], "r");
        // checks imagee_ptr isn't null and exits if is
        if (image_ptr == NULL)
            fprintf(stderr, "Can't open image file\n");
            return 2;
        // buffer to store blocks from image file
        BYTE block[512];
        // ptr for jpg files
        FILE *jpgrec_ptr = NULL;
        // variable to count number of jpgs found
        int jpg_count = 0;
        // read 512 bytes into a buffer
        while ((fread(&block, sizeof(BYTE), 512, image_ptr)) != EOF)
            // checks block's 1st 4 bytes for signature jpg header
            if (block[0] == 0xff && block[1] == 0xd8 &&
                block[2] == 0xff && (block[3] & 0xf0) == 0xe0)
                // array to store jpeg filename
                char filename[8];
                // create filename for jpg
                sprintf(filename, "%03i.jpg", jpg_count);
                // open jpg file for writing
                jpgrec_ptr = fopen(filename, "w");
                // write block to jpg file
                fwrite(&block, sizeof(BYTE), 512, jpgrec_ptr);
                // jpg found, increase jpg_count by 1
            // writes block to jpg file
                fwrite(&block, sizeof(BYTE), 512, jpgrec_ptr);
            // has a jpg been found?
            // if jpg_count has increased by 1...
            // if (jpg_count = jpg_count + 1)

    I'm sorry for being so entry-level and I do get I'm asking for an extraordinary amount of patience. I was really doing ok until recover and then the bottom just dropped from under me. My thanks for any help .


A very well written question. It shows that you're thinking correctly but just need a little nudge and a little more confidence in your skills. ;-)

Now, to answer each point in your question:

  1. It is structured correctly and you are correct that a conditiion is appropriate to detect whether an output file has been opened. Think about what conditions can indicate this. What is the value of jpg_count? Or, what is stored in the output file pointer before the first file is opened? See point 4.

  2. This is the correct way to handle this. It's a scope issue, but I suspect that you were actually creating the pointer inside the if code block, which would mean that it would cease to exist outside the if code block, so the else statement wouldn't see it. Best practice here would be to create it outside the while loop.

  3. First, let's deal with the while loop test condition. You're comparing the return value of the fread to EOF. fread returns an integer, not an eof. You should google feof and take a careful look at what the return value actually represents and think about what is returned when a read is successful, and especially what is returned when EOF is reached. What is read when the file pointer has hit the end of the file? Second, a common error is to check the pointer for EOF and do the read inside the read. This usually results in an extra read attempt when EOF has been reached. I'll let you study the other questions to understand why.

  4. It's absolutely correct to use an if condition to decide whether to write the code block out to the output file. As I said before, what are the conditions that will check this? Is the file counter greater than its initial value? Is the output file pointer still null? If this doesn't jog your memory, hover your mouse over the following spoilers, but you should try to figure them out first:

if( counter == 0 ) {...}


if (file_pointer == NULL) {...}

Here's another tip. The = operator is an assignment operator. The == operator is the comparison operator for equality. Don't confuse the two. The first always does an assignment, changing the left variable and always results in true, while the second actually checks for equality without altering values.

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

  • Checking fread and feof return values really helped. Can't explain why it didn't take hold given how many times I watched the walkthru. Has me checking the return value on every function I call! Figured out (1) I always want the block to write it was just to what file which (2) helped me see the very first condition I came up w/to test for a jpg (the inverse of yours) wasn't the problem, but where I had it made the file close after every block. Where can really screw me up--it reads top to bottom, but loops from the inside out. Balancing them can be hard. Thanks for the really big nudge! :-) – Lindsey Jul 27 '17 at 16:36

You must log in to answer this question.

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