0

Help please!

My code recovers all of the images, and they can all be viewed, but it fails check50.

Would anyone be kind enough to take a look and point me in the right direction?

Here's a link to the sandbox where you can view more info about the errors, and my code is below.

Thanks in advance to anyone that can help.

// create buffer array of 512 bytes
BYTE buffer[512];    

// create counter for JPEG filenames
int counter = 0;

// create char array to hold filename string
char filename[8];

// open memory card file
FILE* inptr = fopen("card.raw", "r");

if (inptr == NULL)
{
    printf("Could not open memory card.\n");
    return 1;
}

// declare file pointer for outfile
FILE* outptr = NULL;

// load blocks of 512 bytes into buffer until end of memory card
while (fread(&buffer, sizeof(BYTE)*512, 1, inptr) == 1)
{
    // check for JPEG signature
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] == 0xe0 || buffer[3] == 0xe1) )
    {
        // check if file is already open
        if (outptr != NULL)
        {
            // close any open files
            fclose(outptr);
        }

        // create a new JPEG file
        sprintf(filename, "%03d.jpg", counter);
        counter ++;

        // open the file
        outptr = fopen(filename, "a");

        if (outptr == NULL)
        {
            fclose(inptr);
            fprintf(stderr, "Could not create %s.\n", filename);
            return 2;
        }
    }

    // if no file is open
    if (outptr == NULL)
    {
        // skip over the current memory block
        fseek(inptr, 512, SEEK_CUR);
    }

    else
    {   
        //write to the file
        fwrite(buffer, 512, 1, outptr);
    }
}

// close outfile
fclose(outptr);

// close infile
fclose(inptr);

return 0;
2
  • How is BYTE defined? Aug 11 '16 at 13:26
  • Ah yeah, I only posted the code inside main. Above main I defined BYTE as typedef uint8_t BYTE;
    – tom-p-uk
    Aug 11 '16 at 13:38
1

If you download and try your program on the prior year's card.raw, you will get a seg fault.

To get that file: cs50.tv/2014/fall > Problem Sets > Problem Set 4: Forensics > Standard Edition > Distribution Code > index > jpg

If you want the fun of troubleshooting and debugging, have at it. Or you can hover below for a spoiler.

The problem is here fseek(inptr, 512, SEEK_CUR);. Why you doin' that? If the program uses a different card.raw (which check50 does!), it could totally skip an all important jpg header block!. Just let the while read the next block.

And another thing! :) This outptr = fopen(filename, "a"); would require you to remove all the jpgs between runs. Some might even consider it a bug. Conventional wisdom would suggest you open the file in write mode.

1
  • Thanks a lot, that was a big help! Means I can finally draw under a line under Pset4. It's taken way longer than it should have.
    – tom-p-uk
    Aug 12 '16 at 6:37
1

buffer is already a pointer to BYTE, so you should write fread(buffer instead of fread(&buffer.

Writing mode "a" for "append" is an interesting choice.

Also, your read command already consumes those 512 bytes, you don't have to fseek (will ignore just another sector).

1
  • I appreciate the help! Thanks a lot.
    – tom-p-uk
    Aug 12 '16 at 6:37
0

Did you copy bmp.h across and include that for the BYTE type definition? That's what I did originally. It would work perfectly well locally, but the automated testing doesn't like that when it comes to compiling recover. Use this in recover instead:

hash include (open arrow) stdint.h (close arrow)

typedef uint8_t BYTE;

typedef uint32_t DWORD;

typedef int32_t LONG;

(stack exchange has some odd formatting when entering code fragments, it thinks it's XML!)

You must log in to answer this question.

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