0

Having some trouble with problem set 3's recover. Running the code below I get a segmentation error but using the debugger I found that the program would not find the start of a JPEG even though the conditions for 'start' are met.

Any help would be greatly appreciated!

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

bool start (uint8_t a[]);

int main(int argc, char *argv[])
{

    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: recover infile\n");
        return 1;
    }

    char *infile = argv[1];
    char filename[4];
    int n = 0;
    uint8_t array[512];
    bool first = true;
    FILE *outprt[50];

    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    while (true)
    {
        // Read the file
        fread(&array, 1, 512, inptr);

        // If end of memory card
        if (fread(&array, 1, 512, inptr) == false)
        {
            fclose(outprt[n]);

            printf("End of memory card.\n");
            return 0;
        }

        // Is this the start of a JPEG? Is this the first JPEG?
        if (start(array) == true && first == true)
        {
            first = false;

            sprintf(filename, "%03i.jpg", n);
            FILE *img = fopen(filename, "w");

            // Start writing to file
            fwrite(&array, 1, 512, outprt[n]);
        }

        else if (start(array) == true)
        {
            // Close file
            fclose(outprt[n]);
            n++;

            sprintf(filename, "%03i.jpg", n);
            FILE *img = fopen(filename, "w");

            // Start writing the file
            fwrite(&array, 1, 512, outprt[n]);
        }

        else if (first == false)
        {
            // Keep writing the file
            fwrite(&array, 1, 512, outprt[n]);
        }
    }
}


bool start (uint8_t array[])
{
    if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
1

Look at the following code:

while (true)
{
    // Read the file
    fread(&array, 1, 512, inptr);

    // If end of memory card
    if (fread(&array, 1, 512, inptr) == false)

This code executes two successive freads. That means that the data read in the first read is overwritten without being processed. The code is essentially skipping over every other data block - blocks that happen to contain all the signatures.

Understand that the if statement doesn't just test the return value from the fread call, it actually executes the call first. To do what you want, you would just need to delete the first call.

However, you should consider doing the read in the while statement. A while(true) statement is always a dangerous thing that can often lead to an infinite loop, and should be used very sparingly.

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

1
  • Thanks for the response! That did help clear up the code and I have got it working now. I also had to replace the 'outprt' variables to 'img' as the 'outprt' varible wasn't needed. – Chesny Nov 1 '19 at 6:30

You must log in to answer this question.

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