c++ - 将 cout 输出推迟到下一个输出之前
问题描述
我有一些 C++ 控制台程序,它们会定期在输出的最后一行显示进度信息。
在写入下一个实际输出(或更新的进度信息)之前清除此进度线;这可能来自源中的许多不同地方,我目前正在清除每个地方的进度线,例如:
cout << clearline << "Some real output" << endl;
...
cout << clearline << "Some other real output" << endl;
...
cout << clearline << setw(4) << ++icount << ") " << ... << endl;
...
cout << clearline << "Progress info number " << ++iprog << flush;
在这里,'clearline' 是一些(系统相关的)字符串,例如 "\r\33[2K" 清除当前的最后一行。
我更喜欢更干净的东西,它将源更改本地化为将要清除的实际行,就像简单地:
cout << "Progress info number " << ++iprog << flush << defer_clearline;
其中'defer_clearline' 导致'clearline' 的写入被推迟到下一个cout 输出之前,无论发生在什么地方。然后我不需要在所有其他行上使用“clearline”。
我认为如果 'defer_clearline' 是一个操纵器,和/或使用 xalloc() 和 iword(),可能会这样做。但我没有设法得到任何有效的东西。是否有可能做这种事情,如果可以,怎么做?
2020-12-30:编辑以包括缺少的“冲洗”。
解决方案
你可以很容易地设置一个std::cout
包装器:
// Declare the empty struct clear_line and instantiate the object cls
struct clear_line { } cls;
class out {
private:
std::ostream &strm = std::cout;
bool is_next_clear = false;
public:
template <typename T>
out& operator<<(const T& obj) {
if(is_next_clear) {
strm << std::endl << std::endl << std::endl; // clear logic
is_next_clear = false;
}
strm << obj;
return *this;
}
out& operator<<(const clear_line& _) {
is_next_clear = true;
return *this;
}
};
这很简单地存储了一个is_next_clear
布尔值,用于判断是否应该清除下一个常规输出。然后,在一般情况下(模板化operator<<()
),我们运行您的清晰逻辑并在is_next_clear
适用时翻转标志。然后像往常一样输出。
然后,operator<<()
对于对象的情况, 被重载clear_line
。所以如果其中一个被发送,我们知道翻转is_next_clear
标志,但实际上不输出任何东西。
这是一个使用示例:
int main() {
out o;
o << "Some real output" << cls;
o << "Some other real output";
return 0;
}
这是在行动:https ://ideone.com/0Dzwlv
如果你想使用endl
,你需要为它添加一个特殊的重载,因为这个答案表明:https ://stackoverflow.com/a/1134467/2602718
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
out& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return its value
manip(strm);
return *this;
}