crecoverfeof

Exiting out of file with feof function


I am trying to make a photo extraction program stop when it detects it is at the end of the file to be extracted. I did this by placing an if condition:

if (feof(file))
{
   return 2;
}

After a fread function:

fread(array, 1, 512, file);

So that if fread reads to the end of the file, then feof will trigger and thereby end the program. This is my code:

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

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Invalid entry.\n");
        return 0;
    }

    int counter = 1;
    FILE* images;
    char jpg_name[8];

    // Check if bytes are jpg. signatures.
    for (int n = 0; counter < 51; n = n + 512)
    {
        // Open file for reading.
        FILE *file = fopen(argv[1], "r");
        if (!file)
        {
            return 1;
        }

        unsigned char array[512];
        fseek(file, n, SEEK_SET);
        fread(array, 1, 512, file); // if EOF, won't have 512 to write into!!!
        if (feof(file))
        {
            return 2;
        }
        fclose(file);

        if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
        {
            // Convert integer to string and store into jpg character array. Increment image number.
            sprintf(jpg_name, "%03i.jpg", counter);
            counter++;

            // Open images file to write into, allocate memory to jpg file to write into, write 512 bytes from array into image file.
            images = fopen(jpg_name, "a");
            fwrite(array, 1, 512, images);
            fclose(images);
        }
        else // If 1st 4 bytes aren't jpg signature.
        {
            if (counter > 1)
            {
                images = fopen(jpg_name, "a");
                fwrite(array, 1, 512, images);
                fclose(images);
            }
        }
    }
}

I have also tried placing the condition:

if (fread(array, 1, 512, file) == 512)

Into the program so that it stops running after it reads fewer than 512 bytes to stop automatically stop the program, but this also doesn't seem to be working.

Any clarification or advice would be much appreciated, thank you!


Solution

  • Don't open and close the file each time through the loop. Just read the file in blocks of 512 until this reaches EOF.

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define SIZE 512
    
    int main(int argc, char *argv[])
    {
        if (argc != 2)
        {
            printf("Invalid entry.\n");
            return 0;
        }
    
        int counter = 1;
        FILE* images;
        char jpg_name[8];
    
        // Open file for reading.
        FILE *file = fopen(argv[1], "r");
        if (!file)
        {
            return 1;
        }
    
        unsigned char array[SIZE];
    
        // Check if bytes are jpg. signatures.
        while (fread(array, 1, SIZE, file) == 1)
        {
            if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
            {
                // Convert integer to string and store into jpg character array. Increment image number.
                sprintf(jpg_name, "%03i.jpg", counter);
                counter++;
    
                // Open images file to write into, allocate memory to jpg file to write into, write 512 bytes from array into image file.
                images = fopen(jpg_name, "a");
                fwrite(array, 1, 512, images);
                fclose(images);
            }
            else // If 1st 4 bytes aren't jpg signature.
            {
                if (counter > 1)
                {
                    images = fopen(jpg_name, "a");
                    fwrite(array, 1, 512, images);
                    fclose(images);
                }
            }
        }
        fclose(file);
    }