清空缓冲区是什么意思?

133
我正在学习C++,发现了一些不明白的东西:
输出缓冲区可以被显式地刷新以强制执行写入。默认情况下,读取cin会刷新cout;当程序正常结束时,cout也会被刷新。
因此,刷新缓冲区(例如输出缓冲区):这是通过删除其中所有内容来清除缓冲区,还是通过输出其中所有内容来清除缓冲区?或者刷新缓冲区意味着完全不同的事情吗?
3个回答

172
考虑写入文件。这是一项昂贵的操作。如果在您的代码中,每次只写入一个字节,则每个字节的写入都将非常昂贵。因此,提高性能的常见方法是将要写入的数据存储在临时缓冲区中。只有在有大量数据时才会将缓冲区写入文件。通过推迟写入并一次性写入大块,可以提高性能。
在此基础上,清空缓冲区是将数据从缓冲区传输到文件的操作。
引用:
这是通过删除缓冲区中的所有内容来清除缓冲区还是通过输出缓冲区中的所有内容来清除缓冲区?
答案是后者。

1
谢谢。还有一件事。读取cin会清空cout。这里的“读取cin”是指当用户输入内容时还是当用户被提示输入内容时? - Mohamed Ahmed Nabil
5
使用流运算符从cin读取时,会发生读取cin的操作。通常在读取时需要刷新cout,否则输入可能会出现在提示之前。 - David Heffernan
1
据我所知,您在使用cin和cout时不需要刷新cout,因为它们是绑定的(Stroustrup,《C++程序设计语言》[io.tie])。@DavidHeffernan - sturmer

30

您引用了答案:

可以显式地刷新输出缓冲区,强制将缓冲区写入。

也就是说,您可能需要“刷新”输出才能将其写入底层流(可以是文件,或者在列出的示例中是终端)。

一般情况下,stdout/cout 是行缓冲的:输出不会发送到操作系统,直到您写入换行符或显式刷新缓冲区。优点是,像 std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endl 这样的语句只会向底层的“文件”写入一次,而不是六次,这对于性能来说更好。缺点是像下面这样的代码:

for (int i = 0; i < 5; i++) {
    std::cout << ".";
    sleep(1); // or something similar
}

std::cout << "\n";

将立即输出 .....(有关准确的 sleep 实现,请参见此问题)。在这种情况下,您需要添加额外的 << std::flush 以确保输出被显示。

读取 cin 会清空 cout,因此您不需要显式刷新:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;

使用以下代码:for (int i=0; i<5; i++) { std::cout << "."; sleep(1); } std::cout << std::endl; 不会一次性打印出.....,而是在它们之间加入了1毫秒的时间间隔。当您使用sleep(1000)时,您将更容易注意到这一点。 - Mohamed Ahmed Nabil
这有点误导人,因为 endl 显式地写入一个新行并刷新缓冲区。只有行缓冲需要它写入新行。 - Alex Chamberlain
1
旧的回答,但唯一的评论与内容关系不大,更多是关于示例。您对命名空间(即std::cout)进行了限定,但对endl没有这样做,这也应该需要限定。 - vol7ron
1
我喜欢你的例子。但是我认为 endl 会刷新缓冲区,但在你的例子中,\n 刷新了缓冲区。我感到困惑。 - Naz
2
@Naz \n 不会刷新缓冲区;在他的示例中,缓冲区仅在程序结束时被刷新(C++程序总是在结束时自动刷新缓冲区)。\n 可能只是用于格式化。此外,您是正确的,std::endl会刷新缓冲区(std::flush也会,但这是不言自明的)。 - liamnickell
显示剩余2条评论

6

通过输出所有内容来清除缓冲区。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接