Search code examples
c++iodeque

Extra line on beginning of output


I am supposed to write a very little program analogical to Unix tail function, I'm using std::deque to store the lines I read by std::getline from supplied file. Pushing in the front, popping from the back.

My problem is, that when I try to print more lines then there are in file, it outputs 1 extra blank line at the begining of output. Here is the source code, TParams is struct with int lncount where number of lines requested is stored, and some other at the moment unimportant stuff...

using namespace std;

deque<string> dq;
int counter = 0;

for(string line; ! (*infile).eof(); getline(*infile, line)){
    dq.push_front(line);

    // not needed lines dropped immediately
    if(counter++ >= TParams.lncount)
        dq.pop_back();
}

int iter = (TParams.lncount > dq.size()) ?
           (dq.size() - 1) : (TParams.lncount - 1);

assert(iter < dq.size());

for(iter; iter >= 0; iter--)
    cout << dq[iter] << endl;

There is some more code regarding -n +num parameter, but it is inside conditions and does not affect this case.

I found out, that there actually is zero length string stored in dq.back() but I have absolutely no idea where it comes from, as it should be the one read from beginning of file, but there is normal line of text.


Solution

  • Your read loop is wrong. First, the value (*infile).eof() isn't really specified; if you have an empty file, it could still return false. And secondly, you're not reading a line before entering the loop to begin with. The classic way to write a loop like this would be:

    std::string line;
    while ( std::getline( *infile, line ) ) {
        //  ...
    }