IOStream库有哪些严重的替代方案? (除了cstdio)

时间:2011-05-30 00:33:37

标签: c++ iostream

我正在寻找一个类似于iostream的库,因为它执行转换,并允许写入内存缓冲区,文件和控制台。但是,我喜欢安全的东西,就像iostream一样。是否有任何严肃的图书馆可以做到这一点?

能够指定事物的输出编码是一个加号。

请注意,我对只是前iostreams的库不感兴趣,因为它们只是为了iostream正在做的事情添加了更多复杂性,例如: boost::format

PreEmptive评论回复:我不想使用cstdio,因为使用该系统不可能让代码与输出位置无关。也就是说,你必须调用一个函数将事物发送到缓冲区,你必须调用另一个函数将事物发送到文件,而另一个函数则用于控制台等。

EDIT2:回应下面的一系列评论:我厌倦了iostreams和cstdio。这里有更具体的原因。我试图让我的“咆哮”脱离这个问题,但人们一直在问我是不是我的摇杆,所以这是我的理由。

cstdio

  • 无法正确处理Unicode字符
  • 如果不进行手动缓冲管理,就无法写入字符串
  • 通常需要支持非标准扩展(例如vsnprintf)才能使用(编辑:好的,C99的C ++标准库现在增加了大部分/全部)
  • 无法在不更改原始代码的情况下更改输出的位置(例如在glibc中的非标准扩展允许您将文件指针视为缓冲区,这样做...但它仍然只是一个非标准的扩展名)
  • 使安全性变得“有趣”(整个章节专门用于解释问题的安全文档,例如“printf”的格式字符串等)
  • 不安全

输入输出流

  • 对客户来说太复杂了。如果你只使用标准库附带的东西,它很棒,但尝试扩展的东西几乎是不可能的。我阅读了整本“标准C ++ IOStreams和Locales”一书 - 这本专题中唯一一本看似可用的书 - 两次 - 我仍然不知道发生了什么。

我喜欢iostreams的概念,甚至是operator<<的使用,有些人似乎不喜欢,但它似乎完全过于设计我。为了成为图书馆的简单客户,有人不应该花费无数个小时阅读书籍。当然,如果你要添加一个新的输出源或类似我能理解的东西,但......客户应该避免这种复杂性。 (这不是图书馆的用途吗?)

这是C ++中唯一令人痛苦的事情,它在其他编程语言中“正常工作”,我认为没有理由变得复杂。

3 个答案:

答案 0 :(得分:6)

BoostSpiritQi输入,BoostSpiritKarma输出。可以读/写任何可以表示为迭代器范围的内容。

答案 1 :(得分:6)

您可能对Fast Format库感兴趣。你可以在他们的网站上看到与其他各种图书馆的比较。

答案 2 :(得分:4)

The {fmt} library:我刚从YouTube talk偶然发现了它,看起来还不错。

已经提出了一种基于{fmt}的格式化工具,用于在C ++ 20中进行标准化:P0645。 P0645和{fmt}都使用类似Python的格式字符串语法,类似于printf,但使用{}作为定界符,而不是%

例如

#include <fmt/core.h>

int main() {
  fmt::print("The answer is {}.", 42);
}

打印“答案是42。”到stdout

为C ++ 20建议的std::format函数:

#include <format>

int main() {
  std::string s = std::format("The answer is {}.", 42);
}

{fmt}的重要功能:

  1. 类型和内存安全性以及格式字符串中的错误,可以选择在编译时报告。

  2. 可扩展性:用户可以为其类型编写格式器,包括自定义格式规范解析器(如Python)。

  3. 紧凑的二进制代码。上面的打印示例编译为:

    main: # @main
      sub rsp, 24
      mov qword ptr [rsp], 42
      mov rcx, rsp
      mov edi, offset .L.str
      mov esi, 17
      mov edx, 2
      call fmt::v5::vprint(fmt::v5::basic_string_view<char>, fmt::v5::format_args)
      xor eax, eax
      add rsp, 24
      ret
    .L.str:
      .asciz "The answer is {}."
    

    printf相当,并且比iostream更好。

  4. 性能:{fmt}比printfiostreams的常见实现要快得多。以下是使用clang的macOS上的tinyformat基准测试的结果:

    ================= ============= ===========
    Library           Method        Run Time, s
    ================= ============= ===========
    libc              printf          1.01
    libc++            std::ostream    3.04
    {fmt} 1632f72     fmt::print      0.86
    tinyformat 2.0.1  tfm::printf     3.23
    Boost Format 1.67 boost::format   7.98
    Folly Format      folly::format   2.23
    ================= ============= ===========