C++ 23 std::print或std::println是否刷新输出流?

li9yvcax  于 2023-02-26  发布在  其他
关注(0)|答案(3)|浏览(604)

在C++ 23之前,当使用std::cout将输出发送到stdout时,在打印字符串末尾添加新行的以下两种方法之间存在区别:

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

第二种方法通常更可取,因为它会刷新输出流,而不需要调用std::cout.flush()
在C++23中,现在有两个新的打印函数,沿着一个新的标准库组件,我们有std::printstd::println
在刷新输出流时,这两个函数有区别吗?
或者,刷新输出流在这些新实现中不再是一个相关的概念?
cppreference的文档未提及冲洗:

6tqwzwtp

6tqwzwtp1#

据我所知,标准没有明确规定;然而,函数调用等价于vprint_nonunicodevprint_unicode,其中stdout是它的第一个参数。这反过来又会产生将vformat写入流的效果。由于vformat不会刷新,因此vprint_(non)unicode不会刷新,因此print也不会刷新。
参见print.fun
注:在html版本中没有,但标准的更新. tex文件确实声明在打印. https://github.com/cplusplus/draft/blob/main/source/iostreams.tex之前存在刷新
如果使用本机Unicode API,函数将在写入\tcode {out}之前刷新\tcode {os}

enxuqcxy

enxuqcxy2#

标准对此未作规定。
我看过print和MS print的Microsoft STL源代码,如果流输出到Unicode控制台,则会刷新流。看起来他们希望避免在多个流输出到控制台时意外拆分多字节字符的字节。

xmjla07d

xmjla07d3#

除非普通文字编码是UTF-8,并且流连接到Unicode感知终端(在实现定义的内容中确定),否则流不会显式刷新。这是一种特殊情况,新添加的<print>保证终端的正确编码(旧的C++ IO不保证)。参见P2093。
但是在这种情况下,流只在写输出之前被刷新,只是为了避免潜在的与底层流的同步问题。
当然,如果连接到交互式终端,底层流通常是行缓冲的,因此向其写入'\n'意味着刷新。但这是实现定义的。根据上面的P2539,似乎在Windows CRT中,如果连接到字符设备,甚至在每次库调用后都有刷新。
因此,它的行为类似于旧C++ IO API中的printf或单个<<。如果需要在上述实现定义的缓冲行为之外执行刷新,则必须像以前一样使用std::flushstd::fflush手动执行。
可能相关的是,没有显式stream/FILE*参数的std::print/std::println将打印到stdout,而不是std::cout,因此如果sync_with_stdio设置为false,则只有std::fflush(stdout)应该是正确的。

相关问题