3

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
    From https://en.cppreference.com/w/c/io/fread `fread does not distinguish between end-of-file and error, and callers must use feof and ferror to determine which occurred.` – Retired Ninja Sep 09 '21 at 04:20
  • 1
    You check the return from `fread()` and when it is `0`, you then check `feof()` and `ferror()` (note: when reading from a network connection, there are further steps involved) – David C. Rankin Sep 09 '21 at 04:48
  • staypersistent, `if (fread(&a1.a, sizeof(a1.a), 1, fp) != 1) break; // if (....) break; ...` – chux - Reinstate Monica Sep 09 '21 at 05:09
  • @chux-ReinstateMonica I tried that too. Then it does not print out any fread outputs. I even moved the if (....) break; statement after the printf statement, it gives me wrong outputs except the 1st line of the file. – staypersistent Sep 09 '21 at 05:54
  • You may want to read [this](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – n. m. could be an AI Sep 09 '21 at 07:27
  • 1
    Unrelated: I don't think `fread`ing a `struct` one field at a time is a good idea. It may be a fun exercise, but don't do that in real code. – n. m. could be an AI Sep 09 '21 at 07:42
  • staypersistent, "it gives me wrong outputs except the 1st line of the file." is telling. Is the file in _lines_ or is it _binary_? Post the file's data content. – chux - Reinstate Monica Sep 09 '21 at 10:33
  • `%s` is not the best specifier to print `char o[MAX_CT];` as it is not certianly _null character_ terminated. Use ``%.11s`. – chux - Reinstate Monica Sep 09 '21 at 10:43

0 Answers0