Программа восстанавливает JPEG с карты, но не проходит проверку CS50 (pset4)
Привет всем могущественным программистам, программа восстановления, кажется, работает отлично. Я прочитал другой пост... запустить Valgrind, и он не показывает утечки. У меня есть все 50 фотографий от 000 до 049. Итак, у меня нет идей. У вас есть ребята? Извините за мои многословные комментарии, но мне нужно отслеживать, что происходит в буквальном смысле.
сообщение об ошибке ЗДЕСЬ (нажмите)
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//fix the name of the file we need to recover from
#define NAME_RAW_FILE "card.raw"
//block size is 512
#define BLOCK_SIZE 512
// "jpg.000" + /n => 8 chars
#define JPEG_NAME_LENGTH 8
// Format of the jpeg file name, using 3 integers padded with 0's
// see https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm
#define JPEG_FILE_FORMAT "%03d.jpg"
// bool checking if the header is the one of a jpg
bool is_jpeg (unsigned char header [])
{
/* this is equivalent to saying if(condition), return TRUE. Return gives back to the function
* any value that comes out of the expression in its scope, in our case the value is TRUE if the
* expression with the equivalences is verified, else false. */
return (header[0] == 0xff
&& header[1] == 0xd8
&& header[2] == 0xff
&& (header[3] & 0xf0) == 0xe0);
}
int main(int argc, char *argv[])
{
if (argc != 1)
{
//no command line argument after programme name
fprintf(stderr, "Usage: ./recover\n");
return 1;
}
// open memory card file
FILE* raw_file = fopen(NAME_RAW_FILE, "r");
if (raw_file == NULL)
{
fprintf(stderr, "Could not open file %s.\n", NAME_RAW_FILE);
return 1;
}
// Store new JPG name and count them
char jpeg_filename[JPEG_NAME_LENGTH];
int jpeg_recoverd_counter = 0;
// Currently opened file we're writing to
FILE* jpeg_file = NULL;
/* we need another buffer to store our jpg data from card.raw
* we use unsigned chars because it's basically equivalent to
* saying bytes */
unsigned char buffer [BLOCK_SIZE];
/* loop over every block of the memory card until EOF.
* What this loop does is checking if the fread function
* returned 512 bytes of size 1, and breaks
* when there is a block of less than 512 bytes : end of file */
while (fread (buffer, 1, BLOCK_SIZE, raw_file) == BLOCK_SIZE)
{
// checks if the first 4 bytes of the block corresponds to a jpg
if (is_jpeg (buffer))
{
// Is there a previous jpg file open? If so, close it.
// This won't close your first jpg file which is set to NULL
// at line 43.
if (jpeg_file != NULL)
{
fclose(jpeg_file);
}
// This line creates a custom filename that will be stored
// in the jpeg_filename array
sprintf(jpeg_filename, JPEG_FILE_FORMAT, jpeg_recoverd_counter++);
// Now that I have the name of the file stored in jpeg_filename
// I open a file in reading and writing mode with that name
jpeg_file = fopen(jpeg_filename, "w+");
// Check that jpeg_file opened successfully
if(jpeg_file == NULL)
{
fclose(raw_file);
fprintf(stderr, "recover: %s: Error creating file", jpeg_filename);
return 1;
}
}
/* At this stage, if no jpeg was found then no jpeg_file was opened.
* so I create a condition to skip any initial bytes not belonging to
* a jpeg by checking if there is a jpeg_file open. If we do have a jpeg
* file open, then write into it */
if (jpeg_file != NULL)
{
/* So, if I do have a jpeg file opened, then I want to write into it
* but I also want to make sure that the writing succeeds, so I encase
* fwrite function in a if condition that checks the return value of the
* function (BLOCK_SIZE). If the writing did not succeed then close everything
* and print error. */
if(fwrite(buffer, 1, BLOCK_SIZE, jpeg_file) != BLOCK_SIZE)
{
fclose(jpeg_file);
fclose(raw_file);
fprintf(stderr, "recover: %s : Error writing the file\n", jpeg_filename);
return 1;
}
}
}
// Close last file open, checking that we ever opened one (imagine card.raw had no jpeg!)
if(jpeg_file != NULL)
{
fclose(jpeg_file);
}
// Was there an error reading from the card?
if(ferror(raw_file))
{
fclose(raw_file);
fprintf(stderr, "recover: %s: Error reading file\n", argv[0]);
return 1;
}
// Else, all good.
fclose(raw_file);
return 0;
}