0

This is what I wrote for pset4 recover. The problem is that I am only getting first 2 images (partially, not full images). And also it creates like hundreds of images and says "file size limit exceeded." I thought my outer while loop would stop inner code once fread with 512 bytes and 1 block doesn't work. I think I am kind of close...any hints? Thank you.

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Enter file name!");
    }

    FILE *inptr = fopen (argv[1], "r");
    if (inptr == NULL)
    {
        printf("File does not exist.");
        return 1;
    }

    typedef uint8_t  BYTE;
    BYTE buffer[512];

    char filename[8];
    int counter = -1;

    //loop until fread fails.
    while (fread (buffer, 512, 1, inptr) == 1)
    {
        do
        {
            fread (buffer, 512, 1, inptr);
        }
        while (buffer[0] != 0xff &&
               buffer[1] != 0xd8 &&
               buffer[2] != 0xff &&
              (buffer[3] & 0xf0) != 0xe0);

        counter ++;
        sprintf(filename, "%03i.jpg", counter);
        FILE *img = fopen(filename, "w");
        fwrite (buffer, 512, 1, img);
        do
        {
            fread (buffer, 512, 1, inptr);
            fwrite (buffer, 512, 1, img);
        }
        while (buffer[0] != 0xff &&
               buffer[1] != 0xd8 &&
               buffer[2] != 0xff &&
              (buffer[3] & 0xf0) != 0xe0);
        fclose(img);
    }

    fclose (inptr);
}

1 Answer 1

0

There are a number of issues here. You will need to give your logic a rethink.

First, note that the first (outer) while loop statement's included fread actually does a read. It's not just a test to see if the code has reached an EOF or some other condition.

Next, the outer while read is followed immediately with the do/while loop that contains another fread statement. The effect of this is two consecutive reads, so the data from the first read is discarded without being processed.

Look at the following statement and think about precedence processing:

while (buffer[0] != 0xff &&
           buffer[1] != 0xd8 &&
           buffer[2] != 0xff &&
          (buffer[3] & 0xf0) != 0xe0);

As soon as one of the conditions is evaluated as false, the whole is false. That means that if only one byte of the 4 matches the signature, the condition is true. There's a long explanation, but buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0 is not the same as !(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) This same condition exists in the last inner while loop.

The last inner do/while loop has another problem. It reads, writes, and then checks for a signature, something I call "Ready, Fire, Aim!"

When all these issues interact, they lead to all of the corrupt files. Also, each pass through the outer loop is going to open a new file.

There's a concept called "rubber duck programming". Basically, it says to go through your code and explain to someone or some thing (like a rubber duck) exactly what each line of code does. Often, verbalizing what the code does like this makes you realize where a problem lies.

You should spend some time and go through the code and do a rubber duck analysis, explaining what happens as you "execute" the code. You can also run it through debug50 and study the code flow and the changes in vars as it runs.

Hint: Maybe it would be more efficient to read in a block of data in one place and then decide what to do with it there and then.

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

0

You must log in to answer this question.

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