C++:“std::endl” 与 “ ”
-
03-07-2019 - |
题
许多 C++ 书籍都包含这样的示例代码......
std::cout << "Test line" << std::endl;
……所以我也一直这么做。但我已经看到很多来自工作开发人员的代码,如下所示:
std::cout << "Test line\n";
是否有技术原因选择其中一种而不是另一种,或者只是编码风格的问题?
解决方案
变化的行尾字符无关紧要,假设文件在文本模式下打开,除非你要求二进制文件,否则这就是你得到的。编译后的程序将为编译的系统写出正确的内容。
唯一的区别是 std :: endl
刷新输出缓冲区,'\ n'
不刷新。如果您不想频繁刷新缓冲区,请使用'\ n'
。如果你这样做(例如,如果你想获得所有输出,并且程序不稳定),请使用 std :: endl
。
其他提示
差异可以通过以下方式说明:
std::cout << std::endl;
相当于
std::cout << '\n' << std::flush;
所以,
- 使用
std::endl
如果您想强制立即刷新输出。 - 使用
\n
如果您担心性能(如果您使用的是<<
操作员)。
我用 \n
在大多数线路上。
然后使用 std::endl
在段落末尾(但这只是一种习惯,通常没有必要)。
与其他说法相反, \n
仅当流要发送到文件时,字符才会映射到正确的平台行尾序列(std::cin
和 std::cout
是特殊的但仍然是文件(或类似文件))。
可能存在性能问题, std :: endl
强制刷新输出流。
我记得在标准中读过这个,所以这里是:
参见C11标准,该标准定义了标准流的行为方式,因为C ++程序与CRT接口,C11标准应该在此处管理刷新策略。
ISO / IEC 9899:201x
7.21.3&#167; 7
在程序启动时,预定义了三个文本流,无需显式打开 &#8212;标准输入(用于读取传统输入),标准输出(用于写入) 常规输出)和标准错误(用于写入诊断输出)。最初 打开后,标准错误流未完全缓冲;标准输入和标准 当且仅当可以确定流不被引用时,输出流被完全缓冲 到交互设备。
7.21.3&#167; 3
当一个流是无缓冲的时,字符应该从源或者出现 目的地尽快。否则可能会累积字符 作为块传输到主机环境或从主机环境传输。当流完全缓冲时, 字符旨在作为块时传输到主机环境或从主机环境传输 填充缓冲区。当流被线缓冲时,字符应该是 当换行字符时,作为块发送到主机环境或从主机环境发送 遇到。此外,字符旨在作为块传输到主机 填充缓冲区时,在无缓冲流上请求输入时的环境,或 当在需要传输的线路缓冲流上请求输入时 来自主机环境的字符。支持这些特征是 实现定义,可能会受到setbuf和setvbuf函数的影响。
这意味着 std :: cout
和 std :: cin
完全缓冲当且仅当指的是非互动设备。换句话说,如果stdout附加到终端,则行为没有差异。
但是,如果调用 std :: cout.sync_with_stdio(false)
,那么'\ n'
将不会导致刷新甚至交互设备。否则'\ n'
等同于 std :: endl
,除非管道到文件: c ++ ref on std :: endl 。
如果您要使用 std :: endl
a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;
a)调用operator &lt;&lt;
一次。点击
b)两次调用operator &lt;&lt;
。
他们都会写出适当的行尾字符。除此之外,endl将导致缓冲区被提交。您通常不希望在执行文件I / O时使用endl,因为不必要的提交会影响性能。
没什么大不了的,但 endl将无效在 boost :: lambda 。
(cout<<_1<<endl)(3); //error
(cout<<_1<<"\n")(3); //OK , prints 3
如果你使用Qt和endl,你可能会意外地使用错误的 endl
,今天发生在我身上,我就像..WTF ??
#include <iostream>
#include <QtCore/QtCore>
#include <QtGui/QtGui>
//notice that i dont have a "using namespace std;"
int main(int argc, char** argv)
{
QApplication qapp(argc,argv);
QMainWindow mw;
mw.show();
std::cout << "Finished Execution !" << endl << "...";
// Line above printed: "Finished Execution !67006AB4..."
return qapp.exec();
}
当然这是我的错,因为我应该写 std :: endl
,但是如果你使用 * endl
,qt和使用命名空间std;
如果使用正确的 endl
,它取决于包含文件的顺序。
当然你可以重新编译Qt以使用命名空间,所以你得到上面例子的编译错误。
编辑:忘记提及,Qt的 endl
在“qtextstream.h”中声明。这是QtCore的一部分
* EDIT2:如果使用
std :: cout
或命名空间 std,C ++将选择正确的
,因为 endl
std :: endl
与 std :: cout
位于同一个命名空间,C ++的ADL机制将选择 std :: endl
我一直习惯只使用std :: endl,因为我很容易看到它。
和 参考 这是一 仅输出 I/O 操纵器.
std::endl
将换行符插入到输出序列 os 中并刷新它,就像通过调用一样 os.put(os.widen('\n'))
其次是 os.flush()
.
何时使用:
该机械手可用于生产一条线 立即输出,
例如
当显示长时间运行的进程的输出时,记录多个线程的活动或记录可能意外崩溃的程序的活动。
还
如果生成的进程执行任何屏幕 I/O,则在调用 std::system 之前还需要显式刷新 std::cout。在大多数其他常见的交互式 I/O 场景中,std::endl 与 std::cout 一起使用时是多余的,因为来自 std::cin 的任何输入、输出到 std::cerr 或程序终止都会强制调用 std::cout .flush()。在某些来源的鼓励下,使用 std::endl 代替 ' ' 可能会显着降低输出性能。
如果您打算在自己的笔记本电脑以外的任何地方运行程序,请永远不要使用 endl
语句。特别是如果你写了很多短线或者我经常看到单个字符到文件。使用 endl
可以杀死像NFS这样的网络文件系统。
endl
操纵器等同于'\'
。但 endl
总是刷新流。
std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush
如果您没有注意到, endl
就像按下ENTER键,而&quot; \ n&quot;
就像按ENTER KEY + SPACE BAR。