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

Bil*_*eal 46 c++ iostream

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

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

请注意,我不感兴趣,在图书馆它只是前iostreams的,因为他们只是增加更多的复杂性到什么iostreams的在做,例如boost::format.

PreEmptive注释响应:我不想使用cstdio,因为使用该系统不可能使代码与输出位置无关.也就是说,您必须调用一个函数将事物发送到缓冲区,并且您必须调用另一个函数来将事物发送到文件,而另一个函数则用于控制台等.

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

cstdio

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

输入输出流

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

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

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

smo*_*are 7

{fmt} 库:我刚刚从YouTube 演讲中偶然发现它,它似乎很不错。

基于 {fmt} 的格式化工具已被提议用于 C++20 中的标准化:P0645。P0645 和 {fmt} 都使用类似 Python 的格式字符串语法,它类似于printf's 但{}用作分隔符而不是%.

例如

#include <fmt/core.h>

int main() {
  fmt::print("The answer is {}.", 42);
}
Run Code Online (Sandbox Code Playgroud)

打印“答案是 42”。到stdout

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

#include <format>

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

{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 {}."
    
    Run Code Online (Sandbox Code Playgroud)

    这与printfiostreams相当并且比iostreams好得多。

  4. 性能:{} FMT是大大高于普遍的实现printfiostreams。以下是在 macOS 上使用 clang 进行的 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
    ================= ============= ===========
    
    Run Code Online (Sandbox Code Playgroud)


ild*_*arn 6

提升.精神.Qi为输入,Boost.精神.业力的业力.可以读/写任何可以表示为迭代器范围的东西.

  • 根据OP,流程太复杂,所以现在我们使用Boost Spirit?现在我们有两个问题! (14认同)
  • 我喜欢这两个库 - 我不认为它们可以成为iostream的一般替代品,因为1.与传统库相比,它们的编译时间都非常糟糕,并且好运调试你得到的错误信息.语法错误的事件.对我原来的问题仍然是一个合理的答案,所以+1. (3认同)

iam*_*ind 6

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