Search code examples
c++ifstreamistream

Calling unget when EOF is triggered


I am reading characters from an ifstream, if those characters don't match a certain criteria, then I unget() a number of times equal to those characters. This all works fine up until I get to the end of the file. Then if I try to unget(), the good bit is set to 0.

This means no characters are unget and when I read again I get blank characters. How can I unget without properly if I reach EOF?

Thanks :)

EDIT:

I have attempted to replace my unget() with putback(), however no I am encountering the error that some rather than putting back characters it seems to be overwriting characters in the ifstream. This is the code I am using:

if (substr.length() > 0)
{
    for (int i = substr.length()-1; i >= 0; --i)
    {
        std::cout << "at " << i << ": " << substr.at(i) << " ";
        infile.putback(substr.at(i));
    }
}

Where substr is the string to putback to the stream. I put it back in reverse order, so it is read in the correct order next time.

If the stream has the following string up next ", r1", and I am putting " #1" back to the stream. After the putback, I expect it to read the next 5 characters as " #1, ", however it is reading it as "#r1"... Somewhere the "1, " is being overwritten.

EDIT/SOLVED: Rather than using unget() or putback(), I instead used seekg() and tellg(). I store the starting position with tellg(), then read however many characters, find the matching string and seek back to the start position + the length of the matching string.


Solution

  • First of all, you need to be sure that no iostate bits are set (fail, bad or eof. In C++11 eof bit will be cleared automatically) before calling unget.

    Then check stram state after operation. If failbit is set, then you forgot to clear stream state before calling unget. If badbit is set, then there is an internal error. Possibly stream cannot back any more.

    You are not guaranteed that you can unget even one character, unlike putback, where putting back at least one character should be supported by the library.