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

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

    char *infile = argv[1];
    FILE *input = fopen(infile,"r");

    if (input == NULL)
    {
    fprintf(stderr, "invalid file");
    return 2;
    }



    uint8_t buffer[512];
    int jpegcnt = 0;
    char filename[9];
    FILE *output = NULL;


    while(true)
    {
        do
        {
        fread(&buffer, 512, 1, input);
        }
        while ( buffer[0] != 0xff ||
         buffer[1] != 0xd8 ||
         buffer[2] != 0xff ||
         (buffer[3] & 0xf0) != 0xe0);

    if ( buffer[0] == 0xff &&
         buffer[1] == 0xd8 &&
         buffer[2] == 0xff &&
         (buffer[3] & 0xf0) == 0xe0)
         {
             if (jpegcnt != 0)
             {
                 fclose(output);
             }
             sprintf(filename, "%03i.jpg", jpegcnt);
             output = fopen(filename, "w");
             fwrite(&buffer, 512, 1, output);
             jpegcnt++;

         }
    }
fclose(output);
fclose(input);
return 0;
}

This is my code for the recover task from pset 4. It compiles and when run creates 50 jpeg files, however they aren't actual pictures, just grey and black chequered boxes on the white background. I used to get a segmentation fault when it was run but after changing things around that doesn't happen any more. Any idea as to why the the jpegs are incorrect?

I can't see a problem with the logic but i am very new to this. I thought it may be to do with the way i'm using the functions?

1

The code above searches for signature blocks and, when found, closes the previous file and opens a new file. While it will correctly skip the garbage data before the first signature block, it will also skip all of the data blocks between signature blocks. These blocks contain image data and needs to be added to the image files, not skipped. Because of this, I would also predict that all of your created files are 512 bytes in size.

The image data following each signature block needs to be correctly processed, not skipped.

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

| improve this answer | |
  • Thanks for the quick response. After adding a do while loop at the end that reads from input and writes into output until it finds the start of another jpeg the program now returns the 24 jpegs. However when i ran check50 I realised there was one more problem. the code as posted above and after it was corrected wont end on its own. Ive been using ctrl+c to end it. I counted the curly braces and i quite sure they are all there. I also closed both input and output files and returned 0. I tried a different condition for the ain for loop and that also didnt work. Any ideas? – user19917 Sep 5 '17 at 20:46
  • Oh, I think it may be worse than that. If you're using the input data that I believe is still being distributed, there are more like 50 files. I suspect that your loops are set up such that you're constructively doing two sequential reads without processing the buffer in between them. Without seeing new code, no way to know. If you can't figure it out, please open a new question as this is a different subject. – Cliff B Sep 6 '17 at 3:06

You must log in to answer this question.

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