【问题标题】:Why std::nounitbuf doesn't do anything on MSVC?为什么 std::nounitbuf 在 MSVC 上没有做任何事情?
【发布时间】:2021-04-10 07:53:10
【问题描述】:

我正在编写关于现代 C++ 的课程并想解释刷新操作的工作原理,因此我决定禁用自动刷新,以便仅在 std::cout 被销毁时才写入缓冲区。

为此,只有一个标准函数存在,它是操纵器std::nounitbuf

但是,这不适用于 MSVC

最让我吃惊的是,C 中的替代方法,setvbuf 函数,实际上允许您停用自动刷新。
这让我有点困扰,因为我想教 C++ 而不是 C。

谁能帮助我?谢谢!

#include <iostream>
#include <thread>

int main()
{
    std::cout << std::nounitbuf; // doesn't work (output is two Hello World before the 5 seconds delay)
    //setvbuf(stdout, nullptr, _IOFBF, BUFSIZ); // work (output is one Hello World, then another one after the 5 seconds)

    std::cout << "Hello World" << std::endl;
    std::cout << "Hello World";

    std::this_thread::sleep_for(std::chrono::seconds{ 5 });
}

【问题讨论】:

  • 你能解释一下它是怎么不工作的吗?在程序结束之前,您至少应该得到一行输出,因为 std::endl 调用 flush 以清除刚刚发送到流的行。
  • 因为您使用std::endl 显式刷新缓冲区,所以std::nounitbuf 没有机会完成它的工作。 std::nounitbuf 也是默认设置。
  • 你不明白,即使没有显式冲洗,它也不起作用!这才是重点。如果你愿意,你可以试试:std::nounitbuf 不工作(顺便说一句 std::unitbuf 似乎工作得很好)
  • std::cout 不是单位缓冲的,因此设置 nounitbuf 不会做任何事情。试试std::cerr。请注意,单元缓冲意味着每次插入后刷新;禁用它不会影响std::endl,它会刷新流,也不会影响行缓冲,当您插入'\n' 时会刷新。
  • 那么你能解释一下为什么 setvbuf 在标准输出上工作吗?谢谢!

标签: c++ c++11 visual-c++ cout flush


【解决方案1】:

发件人:https://en.cppreference.com/w/cpp/io/manip/endl

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

尝试从输出中删除std::endl'\n',您将获得所需的行为。正如 Marek 所说,std::nounitbufstd::cout 的默认设置。

【讨论】:

【解决方案2】:

为什么 std::nounitbuf 什么都不做?

很可能是因为标准cout 流的默认unitbuf 标志未设置。 (Standard narrow.stream.objects 要求只为cerr 设置它)。

谁能帮帮我?

C++ 与 stdio 流同步(不缓冲)。你写的std::cout &lt;&lt; "something" 直接FILE*stdout。当它直接到达那里时,stdout 缓冲才是最重要的。

禁用与 stdio 流的同步,然后尝试。阅读std::ios::sync_with_stdio。以下对我有用。

#include <iostream>
#include <thread>
int main() {
    std::ios::sync_with_stdio(false);

    std::cout << "Hello World" << std::endl;
    std::cout << "Hello World\n";

    std::this_thread::sleep_for(std::chrono::seconds{ 5 });
}

【讨论】:

  • 至少在 msvc 和 clang 上仍然无法正常工作(请参阅其他答案)
  • :/ 所以也许它已经设置好了。尝试也取消它。 Seems to work here.
  • 相信我,我已经尽我所能 x)(但 std::unitbuf 正在工作,但这不是我需要的)
  • 从我对 msvc 的测试来看,它仅在使用 setvbuf 并且在 cout 上应用 nounitbuf 时才有效(注意这是 std::cout 的默认标志,因此必须应用 unitbuf禁用它)。
猜你喜欢
  • 2021-08-11
  • 2021-12-20
  • 2011-07-25
  • 2015-06-30
  • 2023-04-06
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多