【问题标题】:how endl mainly affects fully buffered streams?endl 如何主要影响完全缓冲的流?
【发布时间】:2021-07-07 22:01:15
【问题描述】:

https://www.cplusplus.com/doc/tutorial/basic_io/

在以下站点中,就在 cin 标题之前,声明

endl 操纵器产生一个换行符,与插入 '\n' 完全相同;但它还有一个额外的行为:流的缓冲区(如果有)被刷新,这意味着输出被请求物理写入设备,如果它还没有。 这主要影响完全缓冲的流,而 cout(通常)不是完全缓冲的流。

我的问题是,为什么 endl 主要影响完全缓冲的流,而 cout 怎么不是完全缓冲的流?

【问题讨论】:

    标签: c++ c++11 stream cout ostream


    【解决方案1】:

    输出流主要使用三种缓冲策略:

    1. 无缓冲 - 对流的每次写入都会立即写入底层输出设备。
    2. 行缓冲 - 写入流的内容存储在内存中,直到写入换行符或缓冲区已满,此时缓冲区将刷新到底层输出设备。
    3. 完全缓冲 - 对流的写入存储在内存中,直到流的内部缓冲区已满,此时缓冲区会刷新到底层输出设备。

    为什么 endl 主要影响完全缓冲的流

    从上面的描述中应该很明显。如果流没有缓冲,那么std::endl 不会做任何额外的工作;没有要刷新的缓冲区。如果流是行缓冲的,那么写一个换行符无论如何都会刷新缓冲区,所以std::endl 不会做任何额外的事情。只有对于完全缓冲的流,std::endl 才会做任何额外的工作。


    cout 怎么不是完全缓冲的流?

    C++ 语言没有指定用于std::cout 的缓冲策略,但是当程序的标准输出流连接到终端时,大多数实现要么不使用缓冲,要么使用行缓冲。如果 stdout 被重定向到其他东西,比如文件,许多实现将切换到为std::cout 使用完全缓冲的流。

    【讨论】:

    • 非常有帮助,非常感谢!但是当我在 Windows 控制台上打印一些东西时,我怎么能假设 cout 正在使用特定的缓冲策略。
    • 在倒数第二段中你写道,“写一个换行符无论如何都会刷新缓冲区”,这个换行符是否意味着源代码中的一个新语句?
    • “我怎么能假设 cout 正在使用特定的缓冲策略”。您应该假设 std iostream 已完全缓冲并在重要时刷新它们。请记住,默认情况下std::coutstd::cin 绑定,这样当std::cin 请求读取时,std::cout 将自动刷新。
    • “这个换行符是否意味着源代码中的新语句?” 不,它意味着编写一个行尾标记(即'\n' 字符)这样输出设备向下移动到下一行。 std::endl 都写入换行符并刷新输出流(无论使用何种缓冲模式)。
    • 好的。为了更清楚,请解释以下的刷新过程,“cout
    猜你喜欢
    • 2018-08-20
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    相关资源
    最近更新 更多