为什么从流中读取不需要缓冲区刷新

时间:2018-01-04 15:56:07

标签: c++ iostream flush

刚开始通过 C ++ Primer 5th ed进行C ++学习。

本书第6页的第一个例子如下:

#include <iostream>
int main()
{
    std::cout << "Enter two numbers:" << std::endl; 
    int v1 = 0, v2 = 0; 
    std::cin >> v1 >> v2;
    std::cout << "The sum of " << v1 << " and " << v2
        << " is " << v1 + v2 << std::endl;
    return 0;
}

操纵器 endl 插入换行符并刷新缓冲区。

很快,第7页的代码狙击后不久,作者强调了

  

程序员经常在调试期间添加print语句。这样   语句应始终刷新流。否则,如果是程序   崩溃,输出可能会留在缓冲区,导致错误   推断程序崩溃的地方

从代码示例和强调警告中,我觉得在写入流

时执行刷新非常重要

以下是我不理解的部分,如何从流案例中读取,例如 std :: cin ,是否有必要那么冲洗吗?

附加问题:

#include <iostream>

int main()
{
    int sum = 0, val = 1;
    while (val <= 5) {
        sum += val;
        ++val;
        std::cout << sum << std::endl; //test
    }
}

当我将标有 test 的行更改为 std :: cout&lt;&lt;总和&lt;&lt; &#39; \ n&#39;; ,控制台中没有视觉差异。为什么如果每个循环没有刷新,它是否应该按如下方式打印?

1
1 3
1 3 6 
1 3 6 10
1 3 6 10 15

谢谢

2 个答案:

答案 0 :(得分:2)

即使@Klitos Kyriacou说他应该为新问题创建一个新帖子,但在我看来,你的问题都来自于同样的误解。

程序员经常在调试期间添加print语句。此类语句应始终刷新流。否则,如果程序崩溃,输出可能会留在缓冲区中,从而导致程序崩溃的错误推断

此引用并不意味着您需要刷新程序中的每个缓冲区以在控制台上创建任何输出。 通过刷新缓冲区,您可以确保在执行下一行代码之前打印输出。 如果您没有刷新缓冲区并且程序结束,则无论如何都会刷新缓冲区。

因此,您在控制台上看到std::endl\n的相同输出的原因是,将完全相同的文本打印到控制台。在前一种情况下,输出可能稍早一些,因为缓冲区提前刷新。在后一种情况下,稍后刷新缓冲区,但它们将在某个时间刷新。

当您的程序没有正常退出时,报价所涉及的内容,例如当您的程序崩溃或被操作系统中断时。在这些情况下,如果未显式刷新缓冲区,则可能无法将输出写入控制台。 引用要求您知道的是:每当您想要调试崩溃的程序时,您应该显式刷新缓冲区以确保在程序中断之前将调试输出打印到控制台。

请注意,并非所有实现都适用。

来自http://en.cppreference.com/w/cpp/io/manip/endl

在许多实现中,标准输出是行缓冲的,并且写入&#39; \ n&#39;无论如何都会导致刷新,除非执行了std :: ios :: sync_with_stdio(false)。

答案 1 :(得分:0)

引自同一本书第26页:

  

缓冲区用于保存数据的存储区域。 IO工具通常将输入(或输出)存储在缓冲区中并读取或写入缓冲区   独立于计划中的行动。输出缓冲区可以是   显式刷新以强制写入缓冲区。默认情况下   读cin冲洗cout;程序结束时,cout也会刷新   通常