Search code examples
cfilefeof

C--Program not reading end of file correctly


I'm trying to make a basic set of programs where one program asks the user for a set of values which the program writes into a file and where the other program reads the values from the file and prints them to the screen. Here's my code:

The reading program is as follows:

When I run both programs, the first one successfully writes into "inventory.txt", but the read function duplicates whatever was the last set of values. It looks like this:

Please enter item data (part number, quantity, price): 3, 1, 3.0
Please enter item data (part number, quantity, price): 0

Below are the items in your inventory.
Part#   Quantity    Item Price
    3          1    $      3.00
    3          1    $      3.00

I believe the issue is with my while (feof(fp)==0) but I don't quite understand how feof works and I can't figure out how to replace it without using a "break;"

How can I fix this duplication issue?


Solution

  • The reason behind the apparent duplicated line is the feof() behavior. The man says

    The function feof() tests the end-of-file indicator for the stream pointed to by stream, returning nonzero if it is set.

    meaning, feof() tests if the EOF flag has been set. Getting to the end of file, but not over it, does not set the flag. Thus another iteration is performed, that sets the EOF flag, without changing the variables values, giving the impression of a duplicate.

    You could either change the logic and use fgets(), or change the program as something like

    int eof;
    do {  
        eof = fread(&pn, sizeof(int), 1, fp) < 1;
        if ( !eof ) {
           fread(&quantity, sizeof(int), 1, fp);
           fread(&price, sizeof(float), 1, fp);
           printf("%5d\t%8d\t$ %9.2f\n", pn, quantity, price);
        }
    } while ( !eof );
    

    or, lighter

    while ( 1 ) {  
        if ( fread(&pn, sizeof(int), 1, fp) < 1 ) break;
        fread(&quantity, sizeof(int), 1, fp);
        fread(&price, sizeof(float), 1, fp);
        printf("%5d\t%8d\t$ %9.2f\n", pn, quantity, price);
    }