How to detect the end of file using fread() then finish the loop when reading binary file? (Do not use feof) - C language

Viewed 550

I am writing a code which reads a binary file, read each struct fields seperatly, prints out the results, then stop when the file reading reaches the end.

FYI - The binary file contains multiple records with same struct fields

I could figure out how to do it using feof. but, I would like to run this code using only fread() function(No feof). I was told to find fread return value to detect the end of the file but I am struggling how to do it.

If there are alternate ways to do it Please help me out. below is the code

#define MAX_CT 11
#include<stdio.h>
#include<stdlib.h>

//struct variables
struct test
{
    short int a;
    double b;
    short int c;
    int d;
    float e;
    unsigned short f;
    unsigned char g;
    double h;
    unsigned long i;
    short int j;
    char k;
    int l;
    int m;
    int n;
    char o[MAX_CT];
    char p;
    double q;
};

int main(int argc, char **argv)
{
    struct test a1;
    
    FILE *fp;
    
        //Input Checking Error
        if (argc < 2) {
                fprintf(stderr, "Usage: %s input_file\n", argv[0]);
                exit(1);
        }
    
        //binary file to open for reading
        fp = fopen(argv[1], "rb");
    
        //File Checking Error
        if (fp == NULL){fprintf(stderr, "Cannot open the file %s\n", 
                        argv[1]);
                        exit(1);
        }
    
    //Print the field names
    printf("a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q \n");
    
    //Allocate values into struct using fread
    
    while(1) 
    {
        fread(&a1.a, sizeof(a1.a), 1, fp);
        fread(&a1.b, sizeof(a1.b), 1, fp);
        fread(&a1.c, sizeof(a1.c), 1, fp);
        fread(&a1.d, sizeof(a1.d), 1, fp);
        fread(&a1.e, sizeof(a1.e), 1, fp);
        fread(&a1.f, sizeof(a1.f), 1, fp);
        fread(&a1.g, sizeof(a1.g), 1, fp);
        fread(&a1.h, sizeof(a1.h), 1, fp);
        fread(&a1.i, sizeof(a1.i), 1, fp);
        fread(&a1.j, sizeof(a1.j), 1, fp);
        fread(&a1.k, sizeof(a1.k), 1, fp);
        fread(&a1.l, sizeof(a1.l), 1, fp);
        fread(&a1.m, sizeof(a1.m), 1, fp);
        fread(&a1.n, sizeof(a1.n), 1, fp);
        fread(&a1.o, sizeof(a1.o), 1, fp);
        fread(&a1.p, sizeof(a1.p), 1, fp);
        fread(&a1.q, sizeof(a1.q), 1, fp); 
        
        //if file reading reaches the end, stop the loop 
        //(without feof, is there any other way to finish the loop using fread()????

        if(feof(fp)){
            break;
        }
        
    //Print results
    printf("%d, %f, %i, %d, %f, %d, %d, %f, %lu, %i, %i, %i, %i, %x, %s, %c, %f\n", a1.a, a1.b, 
           a1.c, a1.d, a1.e, a1.f, a1.g, a1.h, a1.i, a1.j, a1.k, a1.l, a1.m, a1.n, a1.o, a1.p, 
           a1.q);
    
    }
    
    //close the file
    fclose(fp);
        
    return 0;
}
1 Answers

i prefer

int c = fgetc(filehandle);

so, I can check:

int c = fgetc(filehandle);
if (c == EOF) {
  fclose(filehandle);
  exit(0);
}

note: for EOF, you can alternatively use '\0'. don't use exit(0); in modern programs. Try to design a program logic, that only need "return ERROR;" or "return SUCCESS;" Because you ran into some trouble if "exit" is nested, and you don't know the position in source. So, good idea is, to "strace", and debug, before you deploy your work.

Related