【问题标题】:Portable end of line便携式终端
【发布时间】:2011-02-01 00:43:18
【问题描述】:

有没有办法根据所使用的操作系统自动使用正确的 EOL 字符?

我在想std::eol之类的东西?

我知道使用预处理器指令非常容易,但很好奇它是否已经可用。

我感兴趣的是,我的应用程序中通常会有一些消息,稍后我会将它们组合成一个字符串,并且我想用 EOL 将它们分开。我知道我可以使用std::stringstream << endl,但有时它似乎有点过头了,而不是常规的追加。

【问题讨论】:

    标签: c++ portability eol end-of-line


    【解决方案1】:

    std::endl 被定义为除了将'\n' 写入流并刷新它之外什么都不做(第 27.6.2.7 节)。 Flushing 被定义为对stringstream 没有任何作用,所以你可以用一种漂亮的方式来表达mystringstream << '\n'。您的操作系统上的标准库实现会适当地转换 \n,所以这不是您关心的问题。

    因此,endl 已经是性能和可移植性的终极选择,如果您想有效地写入文件(而不是字符串流),您唯一需要的其他东西就是 << '\n'。好吧,<< '\n' 也确实消除了对stringbuf::flush 的无意义虚拟调用。除非分析表明空函数调用需要时间,否则不要考虑它。

    【讨论】:

    • 我认为在任何地方使用 '\n 都很好,当我写入控制台和文件时,操作系统(读取 Windows)会自动将其处理为 \r\n。在这一点上对我来说已经足够了。
    • @Potatoswatter:也许你指的是(假设它是 C++ 标准)现在是第 27.7.3.8 节?
    • @sturmer 是的,这是对当时流行的 C++03 的引用。数字发生了变化,但该部分被命名为 [lib.ostream.manip]。无论如何,那里真的没什么可看的。它只是说“效果:调用os.put(os.widen(’\n’) ),然后调用os.flush()。”
    • 我想指出 flush 并非毫无意义。如果您使用 cout 语句进行调试,则最好使用 endl,否则您无法保证在您期望它被打印出时打印出该语句。多线程控制台输出也是如此(尽管这种情况即使使用 endl 也是一团糟)
    • @autonomy 这个答案应该在上下文中阅读。此信息流不是cout。多线程需要互斥锁,刷新似乎有助于减少竞争条件的症状,但这不是解决方案。
    【解决方案2】:

    如果要将行分隔符写入流:

    std::cout << '\n';
    

    std::cout << "\n";
    

    std::cout << "whatever you were going to say anyway\n";
    

    如果流是文本模式并且操作系统使用 LF 以外的任何分隔符作为分隔符,它将被转换。

    如果你想写一个行分隔符并刷新流:

    std::cout << std::endl;
    

    如果您出于某种原因具有二进制模式输出,并且您想编写特定于平台的换行符,那么我认为您可能必须间接执行此操作(将 '\n' 写入文本流,然后在二进制模式,看看你得到了什么)。可能有一些方法可以直接从实现中获取换行符序列,我不知道。无论如何,这不是一个好主意:如果您正在以二进制模式写入或读取文件,那么它应该采用独立于操作系统定义换行符的格式,或者根本没有行。这就是二进制模式的意义

    【讨论】:

      【解决方案3】:

      文件,甚至是文本文件,经常在机器之间传输,所以“特定于操作系统的换行符”是矛盾的。

      确实,操作系统在这件事上有发言权,特别是一个操作系统,即 Windows,尽管许多 Windows 程序会正确读取 \n 间隔的文件,即使 winapi 多行编辑控件不会。我建议您考虑两次什么是适合您的:它不一定是您的操作系统推荐的。如果您的文件要存储在可移动媒体上,请不要使用操作系统标准。使用全球标准,0xA。

      【讨论】:

        【解决方案4】:

        只需以文本模式打开文件

        FILE *fp = fopen( "your_file.txt", "w+t" );
        

        然后

        fprintf( fp, "some string and integer %d\n", i );
        fclose(fp);
        

        操作系统将根据其标准处理 EOL。

        【讨论】:

        • 嗯,我是个老派XD
        • 现在您忘记关闭文件了。 :P
        • 出于异常安全的原因,请不要在生产代码中使用 fopen()。使用 STL RAII 等效项。
        • 来吧,这只是一个例子,您是否希望在生产环境中也有一个名为“your_file.txt”的文件?
        • @Simone:很容易看出文件名需要根据您的示例进行调整。几乎不可能看到不应该使用 C 标准库来处理文件。
        【解决方案5】:

        嗯,STL 有 std::endl,您可以将其用作

        std::cout << "Hi five!" << std::endl;
        

        请注意,除了添加结束行之外,std::endl 还会刷新缓冲区,这可能会产生不良的性能后果。

        【讨论】:

        • Err...这不是 STL,这是 iostreams。
        • 我同意 BillyONEal 的观点。此外,当您只需要'\n' 时,只需写'\n',而不是std::endl。在将不必要的 std::endl 替换为 '\n' 后,我曾经看到加速了 8 倍。
        • 哦,我不知道它们是独立的实体。我只是假设它们是因为它们共享名称空间。谢谢指正。
        猜你喜欢
        • 2010-12-12
        • 1970-01-01
        • 2022-08-02
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 2016-06-20
        • 2011-03-06
        • 2013-11-24
        相关资源
        最近更新 更多