繁体   English   中英

endl和“ \\ n”之间的区别及其与刷新输出缓冲区的关系?

[英]Difference between endl & '\n' and their relation with flushing the output buffer?

我刚刚进入竞争性编程领域,因此,读了几篇文章以掌握程序员在用C ++编写代码时应遵循的最佳策略。 我读到某处应该在行尾使用'\\n'代替std::endl ,因为std::endl强制刷新缓冲区。

我不知道什么是“刷新缓冲区”,所以我开始搜索并遇到了这个答案。刷新缓冲区是什么意思? 阅读答案后,我得到“刷新缓冲区”的想法是将输出缓冲区中的所有内容打印并擦除到控制台。

因此,为了检查答案的有效性,我在计算机上制作了此程序。

#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到3的延迟打印0到4。

但是,当我将endl更改为'\\n'我期望结果在15秒后一次全部显示在控制台上。 但是,在与上一种情况下输出相同的延迟之后,才输出了数字。 现在,如果'\\n'不刷新输出缓冲区,我是否应该得到预期的结果?

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

通常,即使std::cout指向tty 并且缓冲区以\\n结尾,即使输出缓冲区未满,标准库也会刷新std::cout (是的,对其他流进行不同的处理)。 在第二种情况下,这正是发生的情况。

如果您希望代码按预期工作,请尝试将输出重定向到文件(然后使用tail -f观看文件)。 这将导致标准输出不是tty,因此不会引起\\n上的刷新。

同样,无论是否为TTY,IIRC, std::cerr都会在\\n上刷新。 如果写入文件,则除非您明确刷新(例如,使用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;
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM