0

As the title suggests my program finds only 28 images and they are unsupported format and won't open (the file names are correct though).

Please can anyone highlight any issues with my code or point me in the right direction.

I have used the debugger and it seems to be an issue with starting a new jpeg at the end of the old one.

Thanks a lot.

#include <cs50.h>
#include <stdio.h>

#define BLOCKSIZE 512

int main(int argc, char *argv[])
{
    // check correct usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: recover file\n");
        return 1;
    }

    // address of argv[1] stored in infile
    char *infile = argv[1];

    // file pointer to open infile for reading
    FILE *card = fopen(infile, "r");

    // check file opens/exists
    if (card == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    int j = 0;
    int counter = 0;

    // alocate memory for block
    unsigned char block[BLOCKSIZE];

    while(j < 1)
    {
        // read block from card and check for end of file
        fread(block, 1, BLOCKSIZE, card);
        if (fread(block, 1, BLOCKSIZE, card) == BLOCKSIZE)
        {
            // check for jpeg
            if (block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && (block[3] & 0xf0) == 0xe0)
            {
                // store file name
                char jpegname[8];
                sprintf(jpegname, "%03i.jpg", counter);

                //open file (jpegfile is pointer to it)
                FILE* jpegfile = fopen(jpegname, "w");

                // write block from card to file
                fwrite(jpegfile, 1, BLOCKSIZE, card);

                int i = 0;

                // for rest of jpg, keep writing blocks to image
                while(i < 1)
                {
                    fread(block, 1, BLOCKSIZE, card);

                    // check for end of file
                    if (fread(block, 1, BLOCKSIZE, card) == BLOCKSIZE)
                    {
                        if (block[0] != 0xff && block[1] != 0xd8 && block[2] != 0xff && (block[3] & 0xf0) != 0xe0)
                        {
                            fwrite(jpegfile, 1, BLOCKSIZE, card);
                        }

                        // until another jpg starts
                        else
                        {
                            fclose(jpegfile);
                            counter++;

                            // stop loop when new jpeg starts
                            i++;

                            // go to start of block ready for main loop
                            fseek(card, -BLOCKSIZE, SEEK_CUR);
                        }
                    }
                    // stop loop if end of file reached
                    else
                    {
                        fclose(jpegfile);
                        i++;
                    }
                }
            }
        }
        // stop main loop if end of file reached
        else
        {
            j++;
        }
    }
}

2 Answers 2

0
// read block from card and check for end of file
        fread(block, 1, BLOCKSIZE, card);
        if (fread(block, 1, BLOCKSIZE, card) == BLOCKSIZE)

This code shows two consecutive freads being executed. That means that the data from the first fread is being discarded immediately. You can guess what kind of damage that does.

It's a common misconception by new programmers that when a call to a function is inside an if or while statement, it doesn't actually execute. The reality is that the function call DOES execute and then the return value from the function is used in the test condition to evaluate the if or while statement.

There may be other issues, but this one is catastrophic enough.

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

2
  • Thanks so much for the info, that was a big step towards it working.
    – ab26221
    Jul 22, 2018 at 20:00
  • While you'll probably get it working by doing this fix, here's a challenge for you. The program can be written with a single fread statement. Can you rewrite it with only one? How about only one fwrite? ;-)
    – Cliff B
    Jul 22, 2018 at 20:13
0

Thanks man. I will try doing that. I realised one major issue that is worth pointing out for anyone who may read this. In my fwrite function I had the read to and write from parts in the opposite places. So the files were empty. Textbook error lol.

You must log in to answer this question.

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