endl和amp;之间的区别'\ n'和它们与刷新输出缓冲区的关系?

时间:2017-11-01 10:53:25

标签: c++ flush

我刚刚进入竞争性编程的世界,因此,正在阅读一些文章,以掌握程序员在用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'没有刷新输出缓冲区,我不应该得到我期望的结果吗?

2 个答案:

答案 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会导致流不刷新。