0

I've been working on Recover a few days now and managed to actually create a program that retrieves the images. The only problem is that they are not retrieved correctly and don't match what they are actually supposed to be. After running debugger, it continues to land on the line "while (fread(buffer, sizeof(buffer), 1, inputfile) == 1)". I have changed that line so many times, but everytime I change it (along with other lines of code), but everytime I do, I get a segmentation fault. I have no idea what to do. Any help would be greatly appreciated!

#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <stdint.h>
#define BLOCKSIZE 512

typedef uint8_t BYTE;

bool found_jpeg(BYTE buffer[])
{
    return (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }
    FILE *inputfile = fopen(argv[1], "r");
    if (inputfile == NULL)
    {
        printf("File not found\n");
        return 1;
    }
    else
    {
    BYTE buffer[BLOCKSIZE];
    FILE *outputfile = NULL;
    char filename[8];
    int counter = 0;
    bool first_jpeg = false;

        while (fread(buffer, sizeof(buffer), 1, inputfile) == 1)
        {
            if (found_jpeg(buffer) == true)
            {
                if (first_jpeg == false)
                {
                    sprintf(filename, "%03i.jpg", counter);
                    outputfile = fopen(filename, "w");
                    if (outputfile == NULL)
                    {
                        return 1;
                    }
                    fwrite(buffer, sizeof(buffer), 1, outputfile);
                    counter++;
                    first_jpeg = true;
                }
                else if (first_jpeg == true)
                {
                    fclose(outputfile);
                    sprintf(filename, "%03i.jpg", counter);
                    outputfile = fopen(filename, "w");
                    if (outputfile == NULL)
                    {
                        return 1;
                    }
                    fwrite(buffer, sizeof(buffer), 1, outputfile);
                    counter++;
                }
            }
            if (first_jpeg == true)
            {
                fwrite(buffer, sizeof(buffer), 1, outputfile);
            }
        }
    fclose(outputfile);
    fclose(inputfile);
    }
}
1

When this code opens a new file, it writes the first 512 byte block to the output file. But what happens next? The code drops down to the last if block:

        if (first_jpeg == true)
        {
            fwrite(buffer, sizeof(buffer), 1, outputfile);
        }

Since first_jpeg is now true, that first 512 byte signature data block gets written out a second time! That's what is corrupting your output files.

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

| improve this answer | |
  • You were definitely right! That last if block was corrupting my output files. I changed the code so many times after this, but still couldn't find a suitable solution for this. After playing around with it for so much, I finally realized that I didn't have to use a boolean condition, I just use the counter instead. I wrote if (counter > 0) and changed a few other lines of code to suit and it worked! Thank you! – Leoness Jun 28 at 22:54
-1

The command line argument for this programm is a file called card.raw, which containes raw data which programm needs to read and extracts pictures from - right?

There is a code line FILE *inputfile = fopen(argv[1], "r"); which opens files for reading and stores file pointer returned by fopen() into inputfile variable. That is a first step to make reading file content possible. Farther to read file content function fread() should be used. Examples can be found here -https://www.tutorialspoint.com/c_standard_library/c_function_fread.htm

In short - fread() doesn't read the whole card.raw file in one go. It should read not more than can be fit be fitted into the buffer BYTE array...

I think in this particular situation it will benefitial to first create a programm that 1) reads card.raw file and 2) writes its content into another file, for example copy_of_card.raw. Nothing more - nothing less.

This way you will get a bit confident with fopen(), fread(), fwrite() and fclose() functions. Before tackling the main objective.

| improve this answer | |
  • Nope. This is not the problem. Also, reading all the data and writing to another file serves no useful purpose to this program. All the file reads and writes are executed correctly, but perhaps too often. See my answer. – Cliff B Jun 25 at 21:54
  • @CliffB I see, you're right – AlStorm Prime Jun 25 at 22:22

You must log in to answer this question.

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