.eof() Trouble -- Infinite loop

I am trying to read from a file that has a title of a book, number of copies of said book, and then the price. Each item is its own line in the text file. The name of the book may be multiple words. This is what I have tested thus far.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ifstream inFile;
    string name;
    int number;
    double price;
    
    inFile.open("inventory.dat");
    
    getline(inFile, name);
    inFile >> number >> price;
    
    while(!inFile.eof())
    {
        cout << name << " " << number << " " << price << endl;
        getline(inFile, name);
        inFile >> number >> price;
    }
    
    cin.get();
    cin.get();
    
    return 0;
    
}

************************ DATA FILE ***********************

Wally Burger
7
3.99
Angie Laberdoodle
3
4.99
Fulgrim
4
9.99
Horus Rising
2
8.99
Shawshank Redemption
1
24.99




The output excludes the name of the book, outputs the first number, which is 7, and the first price which is 3.99 and loops that continuously. Any pointers would be greatly appreciated. As a side note, I am a beginner programmer so there might be a more advanced easier way, but I have not gotten there yet.
Just to update for when someone takes a look at this... I took out the line 23 and line 17, and changed line 21 to cout << name; . This allowed me to read the file correctly and display the information (also adjusting the .dat file to only have the names in there.
After reading 3.99 into the variable "price" from the file with operator>>, the next character to read is the endline after "3.99" (that's just what operator>> does: it skips leading whitespace, and then reads exactly what's asked and not a character more)

You then call getline(), which reads everything up to and including the newline character, it does exactly that: it sees the newline character that's sitting there after the price, and reads that in, and it's done.

Now the next line to read is the line "Angie Laberdoodle". You're now calling "inFile >> number" to read an integer, but "Angie" is not an integer. operator>> reads nothign and sets the failbit on the stream

Your loop never checks the failbit, all input operations do nothing on a stream that has failbit set, and there you have an endless loop.

Two solutions:
1) skip the endline character after reading the price and before calling getline()
2) use getline for all input, and convert to int and to double later (that's the direction you took when you removed lines 17 and 23)

The first one is the easiest, so here it is:

replace "inFile >> number >> price;", both times, with
"inFile >> number >> price >> ws;"


Also, you're duplicating some code. Usually C++ file input loops place the read code inside the loop controlling statement, instead of once before the loop and once again inside:

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
    string name;
    int number;
    double price;
    ifstream inFile("inventory.dat");
    while(    getline(inFile, name)
           && inFile >> number >> price >> ws )
    {
        cout << name << " " << number << " " << price << '\n';
    }
}




Last edited on
Thank you so much for the help. I tried different ways to put that for hours trying to figure it out, searching things on the internet. That made it a lot simpler.

The reason I was duplicating those lines of code for inFile was because the way I was taught in class was to have a prime read, then run the loop until .eof and to do that you need to have another inFile statement at the bottom of the loop. I like this way better. Thanks again.
Topic archived. No new replies allowed.