C ++:“std :: endl”vs“\ n”
许多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
字符被映射到正确的平台序列结束行序列只有当stream是一个文件( std::cin
和std::cout
是特殊的,但仍然文件(或文件样)) 。
有可能是性能问题, std::endl
强制刷新输出stream。
我记得在标准中读到这个,所以这里是:
请参阅C11标准,该标准定义了标准数据stream的行为方式,因为C ++程序与CRT接口连接,因此C11标准应在此处pipe理冲洗策略。
ISO / IEC 9899:201x
7.21.3§7
在程序启动时,三个文本stream是预定义的,不需要明确打开 – 标准input(用于读取常规input),标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。 最初打开时,标准错误stream没有被完全缓冲; 标准input和标准输出stream是完全缓冲的,当且仅当stream可以被确定为不涉及交互设备时。
7.21.3§3
当一个数据stream没有缓冲的时候,字符应该尽可能地从源头或目的地出现。 否则,字符可以积累并作为一个块被传送到主机环境或从主机环境传送。 当一个stream被完全缓冲时,当缓冲区被填满时,字符被打算作为一个块被传输到主机环境或从主机环境传输。 当一个stream是行缓冲的时候,当遇到一个换行符时,字符将作为一个块被传送到主机环境或从主机环境传送出去。 此外,当填充缓冲区,当在非缓冲stream上请求input时,或者在需要从主机环境传输字符的线路缓冲stream上请求input时,字符意图作为块被传输到主机环境。 对这些特征的支持是由实现定义的,并可能通过setbuf和setvbuf函数来影响。
这意味着std::cout
和std::cin
被完全缓冲, 当且仅当它们指向一个非交互式设备时。 换句话说,如果stdout连接到一个terminal,那么行为就没有区别了。
但是,如果调用了std::cout.sync_with_stdio(false)
,那么'\n'
不会导致交互设备的刷新。 否则'\n'
等同于std::endl
除非pipe道到文件: c ++ ref在std :: endl上 。
他们都会写出适当的行尾字符。 除此之外,endl还会导致缓冲区被提交。 执行文件I / O时,通常不希望使用endl,因为不必要的提交可能会影响性能。
如果你打算使用std::endl
,还有另外一个函数调用
a) std::cout << "Hello\n"; b) std::cout << "Hello" << std::endl;
a)呼叫运营商<<
一次。
b)呼叫运营商<<
两次。
不是什么大问题,但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和using namespace std;
如果使用正确的 * endl
则取决于包含文件的顺序。
当然你可以重新编译Qt来使用命名空间,所以你会得到上面例子的编译错误。
编辑:忘了提及,Qt的endl
是在QtCore的一部分“qtextstream.h”中声明的
* EDIT2:如果你有一个using
std::cout
或命名空间std
,C ++将select正确的endl
,因为std::endl
与std::cout
在同一个命名空间,C ++的ADL机制将selectstd::endl
。
我总是习惯于使用std :: endl,因为我很容易看到。
如果你没有注意到, endl
就像按ENTER键,而"\n"
就像按ENTER键+空格键。