何时必须刷新C ++中的输出流?

时间:2014-01-28 07:12:33

标签: c++ coding-style

我理解cout << '\n'优于cout << endl;,但cout << '\n不会刷新输出流。应该何时刷新输出流以及何时出现问题?

什么是冲洗?

6 个答案:

答案 0 :(得分:2)

Flushing强制输出流写入任何缓冲的字符。 Read streamed input/output.

这取决于您的应用程序,在实时或交互式应用程序中,您需要立即刷新它们,但在许多情况下,您可以等到关闭文件并让程序自动刷新它。

答案 1 :(得分:2)

  

何时必须刷新C ++中的输出流?

当您想确保写入其中的数据对其他程序可见时(或者在文件流的情况下),读取与此文件无关的同一文件的其他流;当你想确定即使程序异常终止也要写入输出。

因此,您需要在长时间计算之前打印消息时执行此操作,或者打印消息以指示出错(尽管您通常使用cerr,但每次都会自动刷新输出)。

通常不需要刷新cerr(默认情况下,在每次输出后将unitbuf标志设置为刷新),或者在从{{1读取之前刷新cout (这些流是绑定的,以便在阅读cin之前自动刷新cout。)

如果您的程序的目的是产生大量输出,无论是cin还是文件,那么不要在每行之后刷新 - 这可能会显着降低它的速度。

  

什么是冲洗?

输出流包含内存缓冲区,其写入速度通常比底层输出快得多。输出操作将数据放入缓冲区;刷新将其发送到最终输出。

答案 2 :(得分:1)

如果您正在编写频繁空格的大文件,则刷新可能是灾难性的。

例如

for(int i = 0 ;i < LARGENUMBER;i++)
{//Slow?
  auto point = xyz[i];
  cout<< point.x <<",",point.y<<endl;
}

VS

for(int i = 0 ;i < LARGENUMBER;i++)
{//faster
  auto point = xyz[i];
  cout<< point.x <<",",point.y<<"\n";
}

VS

for(int i = 0 ;i < LARGENUMBER;i++)
{//fastest?
  auto point = xyz[i];
  printf("%i,%i\n",point.x,point.y);
}

endl()经常知道做其他事情,例如在MSVC上以所谓的调试模式同步线程,导致多线程程序,与预期相反,打印来自不同线程的不间断短语。

答案 3 :(得分:1)

首先,你读错了。您是使用std::endl还是'\n' 在很大程度上取决于背景,但如果有疑问,std::endl是 正常的默认值。使用'\n'保留用于其中的情况 你事先知道冲洗是不必要的,而且它是 太昂贵了。

Flushing涉及缓冲。当你写信给 一个流,(通常)数据不会立即写入 系统;它只是被复制到一个缓冲区,将被写入 当它已满或文件关闭时。或者当它是 明确地脸红了。这是出于性能原因:系统 呼叫通常是一种相当昂贵的操作,而且通常是这样 对每个角色来说都不是一个好主意。从历史上看, C有一种称为行缓冲模式的东西,它被刷新了 每'\n',结果证明这是一个很好的妥协 对于大多数事情。由于各种技术原因,C ++没有 有它;使用std::endl是C ++实现同样目标的方法 结果

我的建议是直到你使用std::endl 开始出现性能问题。如果没有别的,那就是 调试更简单。如果你想更进一步,那就有意义了 当您输出一系列线条时使用'\n' 一些陈述。还有特殊情况,如伐木, 您可能希望明确控制刷新。

答案 4 :(得分:0)

这取决于你在做什么。例如,如果您使用控制台警告用户有关长时间的过程...在同一行中打印一系列点...冲洗可能很有趣。对于正常输出,每行一行,你不应该关心冲洗。

因此,对于基于字符的输出或非基于行的控制台输出,可能需要刷新。对于基于行的输出,它按预期工作。

这个其他答案可以澄清您的问题,基于为什么避免使用endl和手动刷新可能有助于提高性能: mixing cout and printf for faster output

关于什么是刷新:当您写入缓冲流(如ostream)时,您无法保证数据到达目标设备(控制台,文件等)。发生这种情况是因为流可以使用中间缓冲区来保存您的数据并且不会停止您的程序。通常,如果缓冲区足够大,它们将保留所有数据,并且不会因I / O设备速度慢而停止程序。您可能已经注意到控制台非常慢。刷新操作告诉流您要确保所有中间数据都到达目标设备,或者至少它们的缓冲区现在是空的。这对于日志文件非常重要,例如,您希望确定(不是100%)一行将在磁盘上而不是在某个缓冲区中。如果您的程序无法丢失数据,这一点变得更加重要,即如果它崩溃,您希望确保最好将数据写入磁盘。对于其他应用程序,性能更重要,您可以让操作系统决定何时为您刷新缓冲区,或者等到关闭流后,例如。

答案 5 :(得分:0)

由于性能原因,I / O库缓冲了发送到流的数据。每当您需要确保数据实际上已经发送到流时,您需要刷新它(否则它可能仍然在缓冲区中,在屏幕上或文件中不可见)。

某些操作会自动刷新流,但您也可以显式调用类似ostream :: flush。

的内容

您需要确保刷新数据,例如,当您有其他程序等待第一个程序的输入时。