Search code examples
c++fstreamseekg

C++ primer 5th edition Chapter 17.5.3 fstream doesn't put new line


This is the sample code from 17 Chapter (17.5.3) of the C++ primer 5th edition book.

int main(void) {

    fstream inOut("test.txt", fstream::ate | fstream::in | fstream::out);
    if (!inOut)
    {
        cerr << "Unable to open file!" << endl;
        return EXIT_FAILURE;
    }

    auto end_mark = inOut.tellg();
    inOut.seekg(0, fstream::beg);
    size_t cnt = 0;
    string line;

    while (inOut && inOut.tellg() != end_mark && getline(inOut, line))
    {
        cnt += line.size() + 1;
        auto mark = inOut.tellg();
        inOut.seekg(0, fstream::end);
        inOut << cnt;

        if (mark != end_mark)
        {
            inOut << " ";
        }

        inOut.seekg(mark);
    }

    inOut.seekg(0, fstream::end);
    inOut << "\n";
    return 0;
}

The content of the file test.txt is:

abcd
efg
hi
j
<This is a blank new line>

The point is, if this file ends with a blank line, this code works as it's expected. In another word, it will change the file into this:

abcd
efg
hi
j
5 9 12 14
<This is a blank new line>

But, if the file doesn't end with a blank new line, it will output like this:

abcd
efg
hi
j5 9 12 

Note that this file doesn't end with a new line. My question is that where is the blank new line? Afterall, there is the code

inOut << "\n";

It should put a new blank line in any case. Where is wrong?


Solution

  • The problem is that by reaching the end of file the stream's bad bit is set. If you add

    inOut.clear();
    

    before the final inOut << "\n" the newline is written as expected, though the length of the line without a newline continues to not be added.