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::cinstd::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::coutstd::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::endlstd::cout在同一个命名空间,C ++的ADL机制将selectstd::endl

我总是习惯于使用std :: endl,因为我很容易看到。

如果你没有注意到, endl就像按ENTER键,而"\n"就像按ENTER键+空格键。