我想跟踪istream中的亚麻,因此想要使用streambuffer过滤器:
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;
}
};
来源:https://stackoverflow.com/a/24861313/7483073
当我尝试通过tellg()读取istreams当前位置时,它在应用流缓冲区过滤器后失败:
int main()
{
std::istringstream input("i am a dummy test string");
std::cout << input.tellg() << std::endl; //prints 0
char c;
input >> c;
std::cout << input.tellg() << std::endl; //prints 1
LineNumberStreambuf ln(input);
std::cout << input.tellg() << std::endl; //prints -1 ??
return 0;
}
编辑:
我仍然无法找出为什么tellg()在重定向streambuffer后返回-1。奇怪的是,从istream中读取仍然是可能的。如果tellg()返回无效位置,怎么会这样呢?