C ++中的行号是什么?

时间:2014-07-21 07:31:09

标签: c++ iostream

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

这是一个测试用例。我正在寻找与GetLineNumber功能相似的东西,在这种情况下会返回最后一个读取令牌的行号。

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

1 个答案:

答案 0 :(得分:4)

您可以使用过滤streambuf,并在那里继续计数:

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

只需将其插入到您的输入中:

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

请注意,行号仅反映所需的输入 穿过streambuf。