0
void foo() {

    ifstream stream;    
    stream.open(name);
    if(stream.fail()){
        cout << "invalid";
        return;
    }

    int p;
    int q;
    string id;
    int r;
    int s;

    stream >> id >> r >>s;

    while( !stream.eof() ) {

        char f[3];
        char w[3];
        char j[3];

        stream.getline(f,3);
        stream.getline(w,3);
        stream.getline(j,3);

        stream >> p;
        stream >> q;
    }

    stream.close();
}

this code is meant to read the first line of a file and save data from there. Then it is meant to save every 3 characters into a separate char array that will later be saved into a member variable on an object that hasn't been impleneted yet. However, when i run it, instead of reading anything, the stream seems to fail and cause an infinite loop. I am pretty sure the file has valid data.

Dai
  • 110,988
  • 21
  • 188
  • 277
  • What's the last `}` for? – GirkovArpa Jun 13 '20 at 04:12
  • oh it was part of a function, i edited it out – iceman harden Jun 13 '20 at 04:13
  • 1
    Why are you mixing `>>` with `getline`? You shouldn't blindly read from file-streams into typed variables because then your program will crash (or have corrupted state) if the file-stream's actual data doesn't coincide with how you're reading it. – Dai Jun 13 '20 at 04:19
  • A common outcome of the issue raised in @Dai 's comment: [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – user4581301 Jun 13 '20 at 04:53

1 Answers1

1

Your loop condition is wrong:

while( !stream.eof() ) {

It should be:

while( stream ) {

In particular, your code is looping infinitely when an input operation fails, because you never reach EOF.

John Zwinck
  • 207,363
  • 31
  • 261
  • 371
  • im not entirely sure why the stream would fail before ending? – iceman harden Jun 13 '20 at 04:27
  • @icemanharden How confident are you that the stream cannot fail before ending? You could try this proposed solution just to (try to) prove to John Zwinck that it doesn't work. :) – JaMiT Jun 13 '20 at 04:33
  • well the solution prevents the infinite loop, but im now stuck with the fact the input still fails and can't be used. – iceman harden Jun 13 '20 at 04:36
  • 2
    @icemanharden You are trying to read something into an integer variable that isn't an integer. Impossible to say what without seeing the input. – john Jun 13 '20 at 04:50
  • A common cause for error with `stream.getline(f,3)` is 3 or more characters were read before the end of the line. `getline` places a null-terminated string in `f`, so at most 2 characters can be read from the line. The third will be used for the null. As soon as a third character is found, `getline` stops dead, places itself in fail state and will not do anything useful until the fail flag is `clear`ed. Often if the bad data still in the stream is not cleaned up after `clear`ing the flag subsequent attempts to read will also fail. – user4581301 Jun 13 '20 at 04:59
  • 1
    The take away: After any IO transaction test the stream state to ensure the transaction succeeded and take whatever measures are logical. In general never loop on EOF. Too many other things can go wrong with IO,and if you're not looking out for them the program will fail. Plus there's always this guy: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). – user4581301 Jun 13 '20 at 05:02