许多C ++书籍都包含这样的示例代码......
std::cout << "Test line" << std::endl;
...所以我也一直这样做。但是我已经看到很多来自像这样的开发人员的代码:
std::cout << "Test line\n";
是否有技术上的理由偏爱另一个,或者仅仅是编码风格的问题?
答案 0 :(得分:422)
变化的行尾字符无关紧要,假设文件在文本模式下打开,除非你要求二进制文件,否则这就是你得到的。编译后的程序将为编译的系统写出正确的内容。
唯一的区别是std::endl
刷新输出缓冲区,'\n'
没有。如果您不希望频繁刷新缓冲区,请使用'\n'
。如果您这样做(例如,如果您想获得所有输出,并且程序不稳定),请使用std::endl
。
答案 1 :(得分:214)
差异可以通过以下方式说明:
std::cout << std::endl;
相当于
std::cout << '\n' << std::flush;
所以,
std::endl
如果要强制立即刷新输出。\n
(如果您使用的是<<
运营商,情况可能并非如此)。我在大多数行上使用\n
然后在段落的末尾使用std::endl
(但这只是一种习惯,通常不是必需的。)
与其他声明相反,\n
字符仅在流转到文件(std::cin
且std::cout
是特殊的但仍然是特定的时候才会映射到行序列的正确平台末尾文件(或类文件))。
答案 2 :(得分:40)
可能存在性能问题,std::endl
会强制刷新输出流。
答案 3 :(得分:26)
我记得在标准中读过这个,所以这里是:
参见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
,除非汇总到文件:c++ ref on std::endl。
答案 4 :(得分:23)
如果您要使用std::endl
a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;
a)调用运算符<<
一次。
b)两次调用operator <<
。
答案 5 :(得分:18)
他们都会写出适当的行尾字符。除此之外,endl将导致缓冲区被提交。您通常不希望在执行文件I / O时使用endl,因为不必要的提交会影响性能。
答案 6 :(得分:11)
不是什么大问题,但是endl won't work中的boost::lambda。
(cout<<_1<<endl)(3); //error
(cout<<_1<<"\n")(3); //OK , prints 3
答案 7 :(得分:9)
如果你使用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
在“qtextstream.h”中声明,这是QtCore的一部分
* EDIT2:如果您有endl
using
或名称空间std::cout
,C ++会选择正确的std
,因为std::endl
是相同的命名空间为std::cout
,C ++的ADL机制将选择std::endl
。
答案 8 :(得分:2)
我一直习惯只使用std :: endl,因为我很容易看到它。
答案 9 :(得分:1)
我从未见过有人说过 '\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 重现。
我第一次看到它时非常困惑。
答案 10 :(得分:0)
使用reference这是仅输出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代替'\ n'可能会显着降低输出性能。
答案 11 :(得分:0)
如果打算在自己的笔记本电脑以外的其他任何设备上运行程序,则永远不要使用endl
语句。尤其是如果您要写很多短行或者我经常在文件中看到单个字符。众所周知,使用endl
可以杀死网络文件系统,例如NFS。
答案 12 :(得分:0)
endl
操纵器等效于'\'
。但是endl
总是刷新流。
std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush
答案 13 :(得分:-22)
如果您没有注意到,endl
就像按下ENTER键,"\n"
就像按ENTER键+空格键一样。