如何向流运算符添加缩进 [英] How to add indention to the stream operator
问题描述
在我们的项目中,我们在对象模型中使用c ++流运算符(<<)来打印出易于读取的数据格式.一个简化的示例是这样:
In our project we use the c++ stream operator (<<) in our object model to print out an easy readible format of the data. A simplified example is this:
std::ostream& operator<<(std::ostream & oStream, const OwnClass& iOwnClass) {
oStream << "[SomeMember1: " << iOwnClass._ownMember1 << "]\n";
oStream << "[SomeMember2: " << iOwnClass._ownMember2 << "]\n";
}
在日志记录中产生此结果:
Resulting in this in the logging:
[SomeMember1: foo]
[SomeMember2: bar]
我们现在想要的是能够缩进该运算符的结果.一些调用类可能不希望这样的结果,但是想要在每行之前添加2个空格缩进.我们可以在类中添加一个指定缩进的成员,但这似乎不是一个很好的解决方案.
What we want now is to be able to indent the result of that operator. Some calling class might not want the result like this, but want to add 2 spaces indention before each line. We could add a member to our class specifying the indention, but that does not seem to be an elegant solution.
当然,这不是一个很大的问题,但是如果可以的话,我们的日志记录会更好.
Of course this is not a very big issue, but our logging would be so much nicer if this would work.
谢谢
推荐答案
最简单的解决方案是在
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.)
这篇关于如何向流运算符添加缩进的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!