0

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?

Sinclair
  • 23
  • 4
  • On success, fread() and fwrite() return the number of items read or written -- which you are not checking. Since eof hasn't happened after the first three items are read, you enter your loop again. Since you don't check to see if fread read the 1 item you requested by ignoring the return code. If an error occurs, or the end of the file is reached, the return value is a short item count (or zero). When zero, your items aren't changed. – JohnH Dec 10 '18 at 04:32

2 Answers2

0

Seems normal. When the last line is read, the last character (the "0" you use to signify the termination of input) is not read yet, thus, feof(fp) returns 0, and the program enters the loop one more time.

rect0x51
  • 605
  • 1
  • 6
  • 11
0

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);
}
Julius
  • 116
  • 4