我刚刚进入竞争性编程的世界,因此,正在阅读一些文章,以掌握程序员在用c ++编写代码时应遵循的最佳策略。
我在某处读到应该在行尾使用'\n'
代替std::endl
因为std::endl
强制缓冲区刷新。
我不知道'冲洗缓冲区'是什么意思所以我开始搜索它并且遇到了这个答案What does flushing the buffer mean?在读完答案之后,我得到“冲洗缓冲区”的想法就是打印&将输出缓冲区中的所有内容清除到控制台。
所以,为了检查答案的有效性,我在我的机器上制作了这个程序。
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
struct timespec tim, tim2;
tim.tv_sec = 3;
tim.tv_nsec = 0;
for(int i=0; i<5; i++)
{
cout << i << endl;
nanosleep(&tim , &tim2);
}
return 0;
}
我执行程序时得到的结果符合预期。循环打印0到4,每次迭代后延迟3秒。
然而,当我将endl
更改为'\n'
时,我希望结果会在15秒后立即显示在控制台上。但是,在前一种情况下输出相同的延迟后输出数字。现在,如果'\n'
没有刷新输出缓冲区,我不应该得到我期望的结果吗?
答案 0 :(得分:3)
std::endl
强制刷新流。这并不意味着没有它就不会发生冲洗。
通常,标准库将刷新std::cout
(并且,是的,其他流的处理方式不同),即使输出缓冲区未满,如果std::cout
指向tty 和< / em>缓冲区以\n
结尾。在你的第二个案例中,这正是发生的事情。
如果您希望看到代码按预期工作,请尝试将输出重定向到文件(然后使用tail -f
观看文件)。这将导致标准输出不是tty,因此不会导致\n
上的刷新。
此外,IIRC,std::cerr
在\n
上刷新,无论是否为TTY。如果您写入文件,除非您明确刷新(例如,使用std::endl
),否则它永远不会刷新。
已编辑添加
我无法使用stderr或stdout,但以下内容会在最后打印所有数字:
#include <iostream>
#include <fstream>
#include <time.h>
using namespace std;
int main()
{
struct timespec tim, tim2;
tim.tv_sec = 3;
tim.tv_nsec = 0;
ofstream out("output");
for(int i=0; i<5; i++)
{
out << i << "\n";
nanosleep(&tim , &tim2);
}
return 0;
}
答案 1 :(得分:1)
您无法完全控制何时刷新缓冲区。当您将\n
插入流中时,有些系统会将其刷新,其他系统则不会。
只是因为flush
确实刷新了流,这并不意味着不调用flush
会导致流不刷新。