Apologies for including all my (60 lines) of code, but I've been thoroughly confused by this for a while. I've written code to do Recover, and it's working fine and recovers images perfectly--it just puts all images in a name one number higher than they should be. That is, all the images are shifted up by one, and 000 is left empty (050 is the last image created, where it should be 049). I haven't found any logical reason for this to be given the code I've written, despite doing rubber-duck debugging several times. It must be an obvious error staring me in the face--any ideas?
Also, I was unsure why I didn't have to include:
fread(&buffer, 512, 1, rawFile)
after the while() statement, since I would imagine I would actually have to execute the read command at some point for the write command to work later on--but this turns out not to be the case, as you can see from the lack of fread after while(), and I still don't know why. I suspect it's because the fread inside of the while statement somehow automatically writes to buffer even though it's just a conditional being checked inside a while loop?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
int main(int argc, char *argv[])
{
// Takes input file that you want to recover images from and validates it is a meaningful input
while (argc != 2)
{
fprintf(stderr, "Usage: ./recover image");
return 1;
}
if (!(fopen(argv[1], "r")))
{
fprintf(stderr, "Image cannot be opened./n");
return 2;
}
// creates pointer to access the input file in read mode readily by dereferencing this pointer
FILE *rawFile = fopen(argv[1], "r");
// creates a buffer array that will store values that are read throughout the program
unsigned char buffer[512];
// creates a counter that keeps track of how many JPEGs have already been made so you can
//give an appropriate name to the most recent JPEG file created
int counter = 0;
// defines the string filename for use in sptrintf()
char filename[8];
// baseline global definition of outfile for each picture we create
FILE *img = NULL;
// checks for END OF FILE
while (fread(&buffer, 512, 1, rawFile) == 1)
{
// checks if the block of data we just scanned is in fact the start of a JPEG file
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// checks the second conditional--have we already found a JPEG?
if (counter == 0)
{
// if yes->no, then just make a JPEG file img and write the block into it, nothing to close
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
counter++;
fwrite(&buffer, 512, 1, img);
// increment counter to reflect the fact that we just created a new JPEG file file the raw source
}
if (counter != 0)
{
// if yes->yes, then close the previous file before creating a new JPEG file
fclose(img);
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
counter++;
fwrite(&buffer, 512, 1, img);
}
}
else
{
//if no->yes, then copy the info in this FAT block to the file currently open
if (counter != 0)
{
fwrite(&buffer, 512, 1, img);
}
}
}
// close any remaining files and exit the program because we've reached END OF FILE
fclose(img);
fclose(rawFile);
}
Thank you so much! Would appreciate commends/constructive criticism on my code more generally, too.