当前位置:  开发笔记 > 编程语言 > 正文

C++:"std :: endl"vs"\n"

如何解决《C++:"std::endl"vs"\n"》经验,为你挑选了8个好方法。

许多C++书籍都包含这样的示例代码......

std::cout << "Test line" << std::endl;

......所以我也一直这样做.但我已经看到很多来自像这样的开发人员的代码:

std::cout << "Test line\n";

是否有技术上的理由偏爱另一个,或者仅仅是编码风格的问题?



1> David Thornl..:

假设文件在文本模式下打开,变化的行尾字符无关紧要,除非你要求二进制文件,否则这是你得到的.编译好的程序会为编译的系统写出正确的东西.

唯一的区别是std::endl刷新输出缓冲区,而'\n'不是.如果您不希望频繁刷新缓冲区,请使用'\n'.如果您这样做(例如,如果您想获得所有输出,并且程序不稳定),请使用std::endl.


@Omnifarious:不应该为错误保留std :: cerr.两个流不会同步在一起,因此如果您输出一些文本到cout,它可能会被缓冲,并且cerr将直接输出到输出,从而产生混合模式显示.将cerr用于它应该用于的(错误)和cout用于它的设计(正常交互).
@LokiAstari:我不会说'stderr`代表"错误".相反,它是用于带外诊断消息,如果你愿意的话.应该可以说`./prog> file`并且只存储真正的程序有效负载,但程序可能希望输出更多的状态信息,即使在正常交互中也是如此.
或者考虑使用`:: std :: cerr`而不是`:: std :: cout`,因为它是无缓冲的,并且每次输出操作都会刷新.
@Lucas:只有'\n'才能识别平台.
"在许多实现中,标准输出是行缓冲的,写入'\n'无论如何都会导致刷新,除非执行了std :: cout.sync_with_stdio(false)." [从这里复制](http://en.cppreference.com/w/cpp/io/manip/endl)
@Omnifarious请不要把你的所有输出都放在`cerr`中.只将错误打印到cerr允许您通过将两个输出流重定向到不同的位置来分离它们.如果我用'2>/dev/null`重定向`cerr`输出,我不希望所有常规输出都消失.同样,如果我将所有常规输出重定向到像`1> output.txt`这样的文件,我希望我的所有输出都没有错误.或者,如果我将它管道传输到`grep`或`more`,我希望管道按预期推送`cout`东西,然后通过执行`3>&1 1>&2 2>&3 |来管道错误.grep`所以请,请不要混合它们.永远.
@Martin York,我同意,这就是`:: std :: cerr`的用途.但是,在我看来,如果你有不希望缓冲的代码,那么你的输出很可能属于`:: std :: cerr`.我想不出任何有理由经常放弃`:: std :: cout`的缓冲.

2> Martin York..:

差异可以通过以下说明:

std::cout << std::endl;

相当于

std::cout << '\n' << std::flush;

所以,

使用std::endl如果要强制立即刷新输出.

\n如果您担心性能,请使用(如果您使用的是<<运营商,则可能不是这种情况).

我用\n在大多数线上.
然后std::endl在段落的末尾使用(但这只是一种习惯,通常不是必需的).

与其他声明相反,\n只有当流转到文件(std::cin并且std::cout是特殊但仍然是文件(或类似文件))时,字符才会映射到正确的行序列末尾.


@LokiAstari:如果您使用<<运算符,您可能不担心性能_ - 为什么?我不知道`operator <<`是不是高性能,还是用于性能的替代方法?请指出一些材料,以进一步了解这一点.
@ legends2k:有一个古老的妻子故事,C++流不如C printf()那样高效.尽管如此,速度的主要差异是由于人们错误地使用C++流引起的.http://stackoverflow.com/a/1042121/14065在C++中,请记住使用C-stream"sync_with_stdio(false)"取消同步iostream,并且不要连续刷新输出.让图书馆在何时完成.http://stackoverflow.com/a/1926432/14065
@Loki:有一个城市传说,`sync_with_stdio`使得iostream像stdio一样快.[它没有](http://stackoverflow.com/q/4340396/103167)
在许多情况下,"立即看到输出"是一个红色的鲱鱼,因为`cout`与`cin`相关联,这意味着如果你从`cin`读取输入,`cout`将首先被刷新.但是如果你想显示一个进度条或什么东西而不从`cin`读取,那么确定,刷新是有用的.
@BenVoigt:我对上面的措辞很谨慎(所以我很满意他们).它不像stdio那样高效(因为它做得更多).**但**人们抱怨的很多性能差距是由于与stdio同步造成的.

3> Martin Becke..:

可能存在性能问题,std::endl强制刷新输出流.



4> Emily L...:

我记得在标准中读过这个,所以这里是:

请参阅C11标准,该标准定义了标准流的行为方式,因为C++程序与CRT接口,C11标准应该在此处管理刷新策略.

ISO/IEC 9899:201x

7.21.3§7

在程序启动时,预定义了三个文本流,无需明确打开 - 标准输入(用于读取常规输入),标准输出(用于写入常规输出)和标准错误(用于写入诊断输出).最初打开时,标准错误流未完全缓冲; 当且仅当可以确定流不参考交互设备时,标准输入和标准输出流被完全缓冲.

7.21.3§3

当流未缓冲时,字符应尽快从源或目的地出现.否则,可以将字符作为块累积并发送到主机环境或从主机环境发送.当流被完全缓冲时,当填充缓冲区时,字符将作为块传输到主机环境或从主机环境传输.当流被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输.此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境. .对这些特性的支持是实现定义的,可能会受到setbuf和setvbuf函数的影响.

这意味着,std::coutstd::cin是完全缓冲当且仅当他们所指的非交互设备.换句话说,如果stdout附加到终端,则行为没有差异.

但是,如果std::cout.sync_with_stdio(false)被调用,那么'\n'即使交互设备也不会导致刷新.否则'\n'相当于std::endl除非管道到文件:c ++ ref on std :: endl.



5> 小智..:

如果您要使用,那里还有另一个隐含的函数调用 std::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a)调用<<一次操作员.
b)呼叫运营商<<两次.


这可能是显而易见的,但它对线程程序产生巨大影响,通常,第一个版本将在一次写入中写入一行,其中第二个版本可能会被其他线程的写入拆分.我经常写自己写std :: cout <<"hello \n"<< std :: flush来避免这种情况.

6> Ferruccio..:

他们都会写出适当的行尾字符.除此之外,endl将导致缓冲区被提交.您通常不希望在执行文件I/O时使用endl,因为不必要的提交会影响性能.



7> Özgür..:

没什么大不了的,但是endl在boost :: lambda中不起作用.

(cout<<_1<



8> smerlin..:

如果你使用Qt和endl,你可能会意外地使用错误endl,今天发生在我身上,我就像..WTF ??

#include 
#include  
#include 
//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如果你有一个usingfor std::cout或者命名空间std,C++会选择正确的,因为std::endl它与std::coutC++的ADL机制将选择相同的命名空间std::endl.


Urgh!谁会想要`使用命名空间std;`?? :-)
讨厌.感谢您的评论,我相信其他人会遇到这个问题.
推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有