【问题标题】:Difference between endl & '\n' and their relation with flushing the output buffer?endl & '\n' 之间的区别及其与刷新输出缓冲区的关系?
【发布时间】:2018-04-13 16:11:46
【问题描述】:

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

【问题讨论】:

  • 顺便说一句,“竞争性编程”和“程序员应该遵循的最佳策略”是完全无关的。竞争性编程会促使您使用任何理智的程序员都不会在实际代码中使用的策略
  • 尝试使用文件作为输出。

标签: c++ flush


【解决方案1】:

std::endl 强制刷新流。这并不意味着没有它就不会发生刷新。

一般来说,如果std::cout 指向 tty 并且缓冲区以\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;
}

【讨论】:

  • 试过 tail -f 但在两种情况下都得到了相同的结果,wiz。 0 1 2 3 4
  • 编辑了答案。看来 stdout 和 stderr 在换行符上是刷新的(或者,至少对于它们何时不刷新有不同的标准)。但是,常规文件的行为与所述相同。
【解决方案2】:

您无法完全控制何时刷新缓冲区。当您将\n 插入流中时,某些系统会刷新它,而其他系统则不会。

仅仅因为flush 确实刷新了流,并不意味着不调用flush 会导致流不刷新。

【讨论】:

    猜你喜欢
    • 2012-03-27
    • 1970-01-01
    • 2021-10-01
    • 2011-05-29
    • 2012-11-12
    • 2011-09-13
    • 2018-09-10
    相关资源
    最近更新 更多