std::cout << "Test line" << std::endl;
...所以我一直都是这样做的。但我看到很多工作开发人员的代码却是这样的:
std::cout << "Test line\n";
你认为是出于技术原因还是仅仅是编码风格的选择?
假设文件以文本模式打开,不同的换行符并不重要,这是默认的模式,除非你要求使用二进制模式。编译后的程序会为所编译的系统写出正确的内容。
唯一的区别在于std::endl
会刷新输出缓冲区,而'\n'
则不会。如果你不想频繁地刷新缓冲区,请使用'\n'
。如果你需要(例如,如果你想获取所有的输出,并且程序不稳定),请使用std::endl
。
::std::cerr
代替::std::cout
,因为它是无缓冲的,并且每次输出操作都会刷新。 - Omnifariousstderr
是用于“错误”的。相反,它是用于带外诊断消息的。如果可以说./prog > file
并仅存储真正的程序有效负载,则应该可以,但是即使在正常交互中,程序可能也需要输出更多的状态信息。 - Kerrek SB下面的例子可以说明这个差异:
std::cout << std::endl;
等同于
std::cout << '\n' << std::flush;
因此,
std::endl
。<<
运算符,则可能并非如此),请使用\n
。我在大多数行上使用\n
。
然后在段落末尾使用std::endl
(但这只是一种习惯而通常不必要)。
与其他说法相反,\n
字符仅在流将写入文件时才映射到正确的平台换行符序列(std::cin
和std::cout
特殊但仍然是文件或类似文件)。
cout
与cin
相绑定,这意味着如果你从cin
读取输入,那么cout
将首先被清空。但是,如果你想要显示进度条或其他内容而不是从cin
读取,那么刷新是有用的。 - C. K. Youngoperator<<
不够高效,或者有哪些替代方案可以提高性能?请指引我查找更多相关资料来进一步了解此问题。 - legends2ksync_with_stdio
可以让 iostreams 的速度像 stdio 一样快。但事实并非如此,详情请参见 https://dev59.com/W-o6XIcBkEYKwwoYTS1D。 - Ben Voigt使用std::endl
会强制刷新输出流,可能导致性能问题。
如果你要使用 std::endl
,那么在其中还有另一个函数调用被隐含了。
a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;
a) 调用一次运算符 <<
。
b) 调用两次运算符 <<
。
std::cout << "Hello" << "\n";
是什么意思? - byxor<<
的调用也将是2次,因此我不会声称需要一个或两个<<
(或两个函数调用总体上)是\n
和endl
之间的区别。 - Enlico我记得在标准中读到过这个问题,下面是翻译:
参考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++参考文献。
它们都会写入适当的换行符。此外,使用endl会导致缓冲区提交。在进行文件I/O时通常不希望使用endl,因为不必要的提交可能会影响性能。
虽然不是什么大问题,但在 boost::lambda 中,endl 无法正常工作。
(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
(后者本应正确),显然有一个 endl
函数在 qtextstream.h 中定义(这是 QtCore 的一部分)。"\n"
代替 endl
完全避开了任何潜在的命名空间问题。
这也是为什么将符号放入全局命名空间(像Qt默认情况下所做的那样)是一个坏主意的很好的例子。using namespace std;
呢? :-) - Steve Folly我从未见过有人说过 '\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个零。cout
/ofstream
时,它的行为与此相同(我尚未在Windows上测试ofstream
)。无论是endl
还是\n
都不能在通过Linux上的xxd
时产生回车。你是不是回复错了答案?你说“像其他人指出的那样”,但这里只有你一个评论。 - TheHardewendl
。格式化输出的 '\n' 才是与平台有关的东西。在 Windows 上,'\n' 的格式化输出也会给出回车符。我怀疑,在 Windows 上输出不会显示 0。有趣的是,如果宽度设置为 1,它在 Windows 上会做什么。 - Troubadourstd::endl
将换行符插入到输出序列中并刷新它,就像通过调用os.put(os.widen('\n'))
后紧接着调用os.flush()
来进行一样。
'\n'
。 - derobertendl
语句。特别是当你将许多短行或像我经常看到的单个字符写入文件时。使用endl
已知会破坏像 NFS 这样的网络文件系统。 - John Damm Sørensen