Line number in a C++ istream?

孤街浪徒 提交于 2019-12-08 03:00:27

问题


Suppose I'm reading tokens from a std::istream. What is a good way to know the number of newlines that have been read from the stream? This is for the purpose of error reporting in a parser. I don't want to use std::getline to read input.

Here is a test case. I am looking for something functionally similar to GetLineNumber, which in this case would return the line number of the last read token.

std::stringstream ss;
ss << "1 \n 2 \n 3 \n";

int x;
while (ss >> x) {
    std::cout << "Line " << GetLineNumber(ss) << ": " << x << std::endl;
}

The output to this example should be:

Line 1: 1
Line 2: 2
Line 3: 3

回答1:


You can use a filtering streambuf, and keep count there:

class LineNumberStreambuf : public std::streambuf
{
    std::streambuf* mySource;
    std::istream* myOwner;
    bool myIsAtStartOfLine;
    int myLineNumber;

    char myBuffer;
protected:
    int underflow()
    {
        int ch = mySource->sbumpc();
        if ( ch != EOF ) {
            myBuffer = ch;
            setg( &myBuffer, &myBuffer, &myBuffer + 1 );
            if ( myIsAtStartOfLine ) {
                ++ myLineNumber;
            }
            myIsAtStartOfLine = myBuffer == '\n';
        }
        return ch;
    }
public:
    LineNumberStreambuf( std::streambuf* source )
        : mySource( source )
        , myOwner( nullptr )
        , myIsAtStartOfLine( true )
        , myLineNumber( 0 )
    {
    }
    LineNumberStreambuf( std::istream& owner )
        : mySource( owner.rdbuf() )
        , myOwner( &owner )
        , myIsAtStartOfLine( true )
        , myLineNumber( 0 )
    {
        myOwner->rdbuf( this );
    }
    ~LineNumberStreambuf()
    {
        if ( myOwner != nullptr ) {
            myOwner.rdbuf( mySource );
        }
    }
    int lineNumber() const
    {
        return myLineNumber;
    }
};

Just insert this into your input:

LineNumberStreambuf ln( std::cin );
//  ...
std::cerr << "Error (" << ln.lineNumber << "): ..." << std::endl;

Note that line numbers will only reflect the input which takes place through the streambuf.



来源:https://stackoverflow.com/questions/24859739/line-number-in-a-c-istream

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!