更新时间:2023-12-06 14:57:28
最简单的解决方案是在
ostream
和实际的流缓冲.像这样:
The simplest solution is to slip a filtering streambuf between the
ostream
and the actual streambuf. Something like:
class IndentingOStreambuf : public std::streambuf
{
std::streambuf* myDest;
bool myIsAtStartOfLine;
std::string myIndent;
std::ostream* myOwner;
protected:
virtual int overflow( int ch )
{
if ( myIsAtStartOfLine && ch != '\n' ) {
myDest->sputn( myIndent.data(), myIndent.size() );
}
myIsAtStartOfLine = ch == '\n';
return myDest->sputc( ch );
}
public:
explicit IndentingOStreambuf(
std::streambuf* dest, int indent = 4 )
: myDest( dest )
, myIsAtStartOfLine( true )
, myIndent( indent, ' ' )
, myOwner( NULL )
{
}
explicit IndentingOStreambuf(
std::ostream& dest, int indent = 4 )
: myDest( dest.rdbuf() )
, myIsAtStartOfLine( true )
, myIndent( indent, ' ' )
, myOwner( &dest )
{
myOwner->rdbuf( this );
}
virtual ~IndentingOStreambuf()
{
if ( myOwner != NULL ) {
myOwner->rdbuf( myDest );
}
}
};
要插入,只需创建一个streambuf的实例:
To insert, just create an instance of the streambuf:
IndentingOStreambuf indent( std::cout );
// Indented output...
indent
超出范围时,一切恢复正常.
When indent
goes out of scope, everything returns to normal.
(对于日志记录,我有一个比较复杂的部分:
LoggingOStreambuf
以__FILE__
和__LINE__
作为参数,设置
myIndent
转换为带有这些参数的加格式的字符串,加上一个时间
标记,在每次输出后将其重置为缩进字符串,收集
所有输出都放在std::ostringstream
中,并自动输出
到析构函数中的myDest
.
(For logging, I have one that is a bit more complex: the
LoggingOStreambuf
takes __FILE__
and __LINE__
as arguments, sets
myIndent
to a formatted string with these arguments, plus a time
stamp, resets it to an indentation string after each output, collects
all of the output in an std::ostringstream
, and outputs it atomically
to myDest
in the destructor.)