Программа восстанавливает 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;
}

0 ответов

Другие вопросы по тегам