我正在尝试让cout缓冲区刷新以在我操作之前查看字符串。我试图通过调用std::flush()
和std::cout.flush()
来刷新缓冲区,但实际上都没有刷新我的输出。
只有对std::endl
的调用才能成功刷新缓冲区。
这是我的代码
std::istringstream stm (game.date());
int day, month, year;
char delim = '/';
std::cout << "Date before: " << game.date() << std::flush; // first flush attempt
std::cout.flush(); // second flush attempt doesnt work
//std::cout << std::endl; // if this is executed the buffer will flush
// Split date string into integers for comparison
stm >> month >> delim;
stm >> day >> delim;
stm >> year >> delim;
std::cout << "Date after: " << " | " << month << "/" << day << "/" << year << std::endl;
这是我的输出
日期之后:| 13年1月31日
日期之后:| 12年3月21日
日期之后:| 11/11/11
日期之后:| 10年10月1日
日期之后:| 1/2/12
因为你可以看到对cout的第一次调用并没有被刷新,但正如我之前所说的,缓冲区将成功刷新endl,它调用flush本身。我目前正在运行Mountain Lion的主机macbook pro上运行带有VirtualBox的Ubuntu 12.04。
我的同花顺电话中是否有任何错误或可能是系统问题?
答案 0 :(得分:7)
std::cout << flush;
和std::cout.flush();
都会刷新std::cout
。
看起来您的代码将回车符(\r
)插入到流中。假设您今年打印,似乎您将其插入char
,其值13
恰好是\r
。这样做的结果是你的后期输出只会覆盖输出,因为它将在同一行上。您可以在刷新流之前显式插入换行符(\n
)来验证这一点。
答案 1 :(得分:4)
cout
上有一个系统缓冲区,它仍会缓冲现代Linux系统中的输出。
要为程序运行禁用它,请使用命令stdbuf
,如下所示:
stdbuf -o 0 ./yourprogram --yourparams
如果需要在调试器中禁用缓冲,请使用如下:
stdbuf -o 0 gdb --args ./yourprogram --yourparams
答案 2 :(得分:1)
Flush仅将流的缓冲区写入实际设备(文件或tty)。
如果这是您所期望的,它不会移动到下一行。
这是设计的。
注意,这里是一个更干净的代码版本,看起来像宣传的那样工作(有或没有刷新):
#include <sstream>
#include <iostream>
#include <vector>
#include <cassert>
struct Game {
std::string _date;
std::string date() const { return _date; }
};
int main()
{
for (Game game : std::vector<Game> { {"01/02/1999"}, {"24/10/2013"}})
{
std::istringstream stm (game.date());
int day, month, year;
char delim = '/';
std::cout << "Date before: " << game.date();
stm >> month >> delim;
assert(stm && '/' == delim);
stm >> day >> delim;
assert(stm && '/' == delim);
stm >> year;
std::cout << " Date after: " << " | " << month << "/" << day << "/" << year << std::endl;
}
}