"std::endl"与" line break "
"std::endl" vs " "
许多C++书都包含这样的示例代码...
std::cout << "Test line" << std::endl;
。所以我也一直这样做。但是我已经看到很多来自工作开发人员的代码,如下所示:
std::cout << "Test linen";
是否有技术原因偏爱一个而不是另一个,或者这只是编码风格的问题?
不同的行尾字符无关紧要,假设文件以文本模式打开,除非您要求二进制,否则您将获得此。 编译的程序将为编译的系统写出正确的内容。
唯一的区别是std::endl
刷新输出缓冲区,而'n'
不会。 如果不希望频繁刷新缓冲区,请使用 'n'
。 如果这样做(例如,如果要获取所有输出,并且程序不稳定),请使用 std::endl
。
差异可以通过以下几点来说明:
std::cout << std::endl;
相当于
std::cout << 'n' << std::flush;
所以
- 如果要强制立即刷新输出,请使用
std::endl
。 - 如果您担心性能,请使用
n
(如果您使用的是<<
运算符,则可能并非如此)。
我在大多数线路上使用n
。
然后在段落末尾使用std::endl
(但这只是一种习惯,通常不是必需的)。
与其他声明相反,只有当流要转到文件(std::cin
并且std::cout
是特殊但静止的文件(或类似文件))时,n
字符才会映射到正确的平台行尾序列。
性能问题,std::endl
强制刷新输出流。
如果你打算使用std::endl
,这里隐含了另一个函数调用
a) std::cout << "Hellon";
b) std::cout << "Hello" << std::endl;
a) 呼叫接线员<<
一次。
b) 呼叫接线员<<
两次。
我记得在标准中读到过这个,所以这里是:
请参阅 C11 标准,该标准定义了标准流的行为方式,因为C++程序与 CRT 接口,因此 C11 标准应在此处管理刷新策略。
ISO/IEC 9899:201x
7.21.3 §7
在程序启动时,预定义了三个文本流,不需要显式打开 — 标准输入(用于读取常规输入),标准输出(用于写入) 常规输出)和标准错误(用于写入诊断输出)。最初 打开时,标准错误流未完全缓冲;标准输入和标准 当且仅当可以确定流不引用时,输出流才会完全缓冲 到交互式设备。
7.21.3 §3
当流未缓冲时,字符旨在从源或 尽快到达目的地。否则可能会累积字符和 作为块传输到主机环境或从主机环境传输。当流完全缓冲时, 字符旨在作为块传输到主机环境或从主机环境传输,在以下情况下 填充缓冲区。当流被行缓冲时,字符应 当换行符 遇到。此外,字符旨在作为块传输到主机 填充缓冲区时的环境,在未缓冲的流上请求输入时,或 当在需要传输 主机环境中的字符。对这些特征的支持是 实现定义,并可能通过 setbuf 和 setvbuf 函数受到影响。
这意味着当且仅当std::cout
和std::cin
引用非交互式设备时,它们才会完全缓冲。换句话说,如果 stdout 连接到终端,则行为没有区别。
但是,如果调用std::cout.sync_with_stdio(false)
,则'n'
甚至不会导致交互设备刷新。否则'n'
等效于std::endl
除非管道到文件:std::endl 上的 c++ ref
它们都将写入适当的行尾字符。除此之外,endl 将导致提交缓冲区。在执行文件 I/O 时,通常不希望使用 endl,因为不必要的提交会影响性能。
大不了的,但endl在boost::lambda中不起作用。
(cout<<_1<<endl)(3); //error
(cout<<_1<<"n")(3); //OK , prints 3
Qt 和 endl
,你可能会意外地最终使用不正确的endl
,这给了你非常令人惊讶的结果。请参阅以下代码片段:
#include <iostream>
#include <QtCore/QtCore>
#include <QtGui/QtGui>
// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
QApplication qapp(argc,argv);
QMainWindow mw;
mw.show();
std::cout << "Finished Execution!" << endl;
// This prints something similar to: "Finished Execution!67006AB4"
return qapp.exec();
}
请注意,我写的是endl
而不是std::endl
(这是正确的),显然在qtextstream.h(这是QtCore的一部分)中定义了endl
函数。
使用 "n"
而不是 endl
完全回避任何潜在的命名空间问题。这也是一个很好的例子,为什么将符号放入全局命名空间(就像Qt默认所做的那样)是一个坏主意。
从未见过有人说的是'n'
受到cout格式的影响:
#include <iostream>
#include <iomanip>
int main() {
std::cout << "\n:n" << std::setw(2) << std::setfill('0') << 'n';
std::cout << "std::endl:n" << std::setw(2) << std::setfill('0') << std::endl;
}
输出:
n:
0
std::endl:
请注意,由于'n'
是一个字符并且填充宽度设置为 2,因此在 'n'
之前只打印 1 个零。
我在任何地方都找不到关于它的任何信息,但它用 clang、gcc 和 msvc 重现。
当我第一次看到它时,我超级困惑。
附参考 这是一个仅输出的 I/O 操纵器。
std::endl
在输出序列 os 中插入换行符并刷新它,就像通过调用 os.put(os.widen('n'))
后跟 os.flush()
一样刷新它。
何时使用:
该机械手可用于立即产生输出线,
例如
显示长时间运行的进程的输出时,记录多个线程的活动或记录可能意外崩溃的程序的活动。
也
在调用 std::system 之前,如果生成的进程执行任何屏幕 I/O,则还需要显式刷新 std::cout。在大多数其他常用交互式 I/O 方案中,std::endl 在与 std::cout 一起使用时是多余的,因为来自 std::cin、输出到 std::cerr 或程序终止的任何输入都会强制调用 std::cout.flush()。在某些来源的鼓励下,使用 std::endl 代替 '' 可能会显著降低输出性能。
来自 GCC 文档:
有些人还认为,向下发送输出流的 endl 只会写一个换行符。这是不正确的;写入换行符后,也会刷新缓冲区。也许这就是写入屏幕时想要的效果 - 尽快取出文本等 - 但是在对文件执行此操作时,缓冲在很大程度上被浪费了:
output << "a line of text" << endl;
output << some_data_variable << endl;
output << "another line of text" << endl;
在这种情况下,正确的做法是将数据写出,让库和系统担心缓冲。如果您需要换行符,只需编写换行符:
output << "a line of textn"
<< some_data_variable << 'n'
<< "another line of textn";
您可以检查 ostream 的文档,或检查实现本身endl
- 在我的案例中,usr/include/c++/11/ostream:684 - 。在那里你会发现:
// Standard basic_ostream manipulators
/**
* @brief Write a newline and flush the stream.
*
* This manipulator is often mistakenly used when a simple newline is
* desired, leading to poor buffering performance. See
* https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
* for more on this subject.
*/
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{ return flush(__os.put(__os.widen('n'))); }
- 在 c++ 中在开关情况下使用和不使用"break"时的不同输出
- 以某种方式告诉编译器"Do not process line of code"
- 使用flag、return、exception、goto或break中止过程
- 注册 Clang 检查器时出错:"out-of-line-definition of register"
- :<command-line>0:3:警告:ISO C++11 要求宏名称后有空格
- Command Line Arguments wxCmdLineArgsArray in wxWidgets
- 使用C 中的链接seam break static变量依赖关系
- 为什么在使用 select() 时连接到带有第二个套接字的服务器"break"第一次连接?
- 我的 break 语句没有中断 for 循环
- 海湾合作委员会 7、aligned_storage 和 "dereferencing type-punned pointer will break strict-aliasing rules"
- qt graphicsscene line subclass
- Xcode 8.3 command line C++
- g++ 在我尝试用 ONE LINE 编译程序时崩溃了
- 为什么在使用LLVM时,std::ifstream的缓冲"break" std::getline?
- QSTACKEDWIDGET区域在Child Widget Line编辑中在ESC上清除
- 这一行是怎么回事: istringstream is( line );
- 需要帮助按 "enter or new line" 以允许用户返回主菜单
- 交叉编译时"DSO missing from command line" 莫斯基托示例
- #line 指令的 nul.h 文件名的文件路径不正确
- "std::endl"与" line break "