C ++ istream中的行号? [英] Line number in a C++ istream?

查看:46
本文介绍了C ++ istream中的行号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我正在从std::istream读取令牌.知道从流中读取换行符数量的好方法是什么?这是为了在解析器中报告错误.我不想使用std::getline读取输入.

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.

这是一个测试用例.我正在寻找功能类似于GetLineNumber的东西,在这种情况下,它将返回最后读取的令牌的行号.

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;
}

此示例的输出应为:

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

推荐答案

您可以使用过滤streambuf,并在此保持计数:

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;

请注意,行号将仅反映输入 通过streambuf放置.

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

这篇关于C ++ istream中的行号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆