代码之家  ›  专栏  ›  技术社区  ›  Head Geek

C++:“STD::Endl”vs“\n”

  •  480
  • Head Geek  · 技术社区  · 16 年前

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

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

    …所以我也一直这样做。但是我看到过很多这样的开发人员编写的代码:

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

    有没有技术上的原因比另一个更喜欢一个,或者这只是一个编码风格的问题?

    12 回复  |  直到 6 年前
        1
  •  410
  •   Uli Köhler    11 年前

    不同的行尾字符并不重要,假设文件是以文本模式打开的,除非您要求使用二进制文件,否则这就是您得到的结果。编译后的程序将为编译后的系统写出正确的东西。

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

        2
  •  204
  •   sabbahillel    9 年前

    差异可通过以下方式加以说明:

    std::cout << std::endl;
    

    等于

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

    所以,

    • 使用 std::endl 如果要强制立即刷新输出。
    • 使用 \n 如果您担心性能(如果使用 << 操作员)。

    我用 \n 在大多数线路上。
    然后使用 STD::Endol 在一段的结尾(但这只是一个习惯,通常不需要)。

    与其他权利要求相反, \n 只有当流要转到文件时,字符才会映射到正确的平台行尾序列。( std::cin std::cout 特殊但仍然是文件(或类似文件)。

        3
  •  40
  •   Richard    11 年前

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

        4
  •  24
  •   Emily L.    9 年前

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

    参见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 .

        5
  •  23
  •   roottraveller    7 年前

    如果要使用 std::endl

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

    a)呼叫话务员 << 曾经。
    b)呼叫话务员 << 两次。

        6
  •  18
  •   Ferruccio    16 年前

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

        7
  •  11
  •   Özgür    16 年前

    没什么大不了的,但是 endl won't work 在里面 boost::lambda .

    (cout<<_1<<endl)(3); //error
    
    (cout<<_1<<"\n")(3); //OK , prints 3
    
        8
  •  9
  •   smerlin    8 年前

    如果使用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 , 但是如果你使用 恩德尔 QT和 using namespace std; 如果正确,则取决于包含文件的顺序 恩德尔 将被使用。 *

    当然,您可以重新编译qt以使用名称空间,因此对于上面的示例,您会得到一个编译错误。

    编辑:忘记提了,qt's 恩德尔 在“qtexstream.h”中声明,它是qtcore的一部分

    *Edt2: C++将选择正确的 恩德尔 如果你有 using 对于 std::cout 或命名空间 std ,因为 STD::Endol 与位于同一命名空间中 性病:咳嗽 C++的ADL机制会选择 STD::Endol .

        9
  •  2
  •   Zee JollyRoger    16 年前

    我一直习惯只用std::endl,因为它很容易让我看到。

        10
  •  1
  •   Kaleem Ullah    7 年前

    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
  •   John Damm Sørensen    6 年前

    如果你打算在你自己的笔记本电脑以外的任何地方运行你的程序,永远不要使用 endl 语句。尤其是如果你写了很多短行,或者像我经常看到的那样,一个文件只有一个字符。使用 恩德尔 知道如何杀死网络文件系统,如nfs。

        12
  •  -20
  •   Samer    9 年前

    如果你没注意到, endl 就像按下Enter键 "\n" 就像按回车键+空格键。