Hi.
I want to read through a file and search for variables saved in it.
However if the stream reads the last char I got errors like EOF.

For example the following code would not work as intended to :

bool BaseFileReader::Valid() const
{
    if (!File.is_open())
    std::cout << "\n\nERROR: File is not open!";
    if (File.fail())
    std::cout << "\nERROR: Either failbit or badbit is set!";
    if (File.eof())
    std::cout << "\nERROR: EOF is set!";

    return (File.is_open() && !File.fail() && !File.eof() && File.good());
}


bool BaseFileReader::LoadFromFile(const char* filepath)
{
    if (!filepath)
    {
        SetERR(ERR_UNKNOWN); // pointer is invalid
        return false;
    }

    File.open(filepath);

    if (!Valid())
    {
        SetERR(ERR_OPENFILE); // Can't open file
        return false;
    }
    
    // Here goes my reading algorithm, but this loop expresses better what the problem is
    for (int i = 0;i < 2;i ++) // Should be printing the whole content two times
    {
        std::cout << "\n" << i+1 << "x print : \n==========\n";
 
        // Last Valid() call would print EOF and fail()
        while(Valid())
            std::cout << (char)File.get();


        std::cout << "\n==========";
        // After EOF I'm not able to set the get-pointer
        File.seekg(std::ios_base::beg);
    }

    SetERR(ERR_GOODBIT);
    Clear();

    return true;
}

The big deal is, that when my Reader reads keywords at the end of a file and then wants to read a keyword before that, it can't.
Since reading the last characters, which represent the variable, would lead to reading the last character of the file.
And that means EOF, so the Reader is not able to read any data, unless I reopen the file.

I already know two ways of solving that.
I could just add a 'non-number' char at the end, so it wouldn't be read by the Reader.

But I find this approach more uglier than solving it by a different code.

My question is if there is a way to "safe" the stream after getting errors like EOF, without reopening it.

Thanks in advance.

Dani AI

Generated

A concise diagnosis and practical fixes.

As suggested, hitting the last character sets the stream error bits (eofbit and sometimes failbit) and those bits are "sticky" — they stop further reads and can make seek operations appear to fail. The correct, minimal recovery is to clear the error state and then rewind the get pointer; also prefer read-while idioms that test the read itself instead of testing eof() before a read.

A robust pattern (read once, reset, read again):

std::ifstream in("file.txt");
char c;

// preferred loop: test the read operation
while (in.get(c)) {
    // process c
}

// reached EOF: reset flags and rewind before another pass
in.clear();                      // clear eof/fail/bad bits
in.seekg(0, std::ios::beg);      // rewind to start
if (in.fail()) { /* handle seek error */ }

// second pass
while (in.get(c)) {
    // process again
}

Practical notes and gotchas:

  • Avoid loops like while(!file.eof()) — eof() becomes true only after a failed read and leads to off-by-one bugs. Use while(file.get(c)), while(file >> token) or while(std::getline(file, line)).
  • In 's code, calling seekg(std::ios_base::beg) is incorrect; use seekg(0, std::ios::beg).
  • clear() without arguments resets all error bits; if you need to preserve other bits you can clear only eofbit via rdstate manipulation, but that’s rarely needed.
  • If multiple random passes are required and the file is small, reading the whole file into memory (string) and parsing that is often simpler and faster than repeated stream manipulation.

These steps remove the need for ugly sentinel characters at EOF and make parsing near-file-end reliable.

Recommended Answers

All 2 Replies

if the EOF flag is set and it's giving you problems with seekg(), try clear()'ing the object and see if that works for ye'.

I can't believe it.
I was searching over cprogramming.com for hours to find a solution and you just solved it, thanks dude !

commented: :) +10
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.