【问题标题】:Do C++ formatting libraries generally fall back to *sprintf for numeric formatting?C++ 格式化库通常会回退到 *sprintf 进行数字格式化吗?
【发布时间】:2011-10-07 07:54:35
【问题描述】:

我想知道“所有”C++ 格式化库是否最终会退回到 *sprintf 函数来格式化数字。

我问这个是因为:

  • 查看 Visual C++ 附带的 iostreams 库,我可以看到输入到流中的数字最终将被格式化为 sprintf_s
  • 据我所知,Boost.Format 只使用了可用的 iostreams 库。
  • FastFormat 最终使用vsprintf 来格式化数字。

那么,是否有 iostreams 实现使用 *sprintf 并自己进行格式化?是否有其他格式库将数字格式转发到 *sprintf 系列函数?

我希望得到以下形式的答案:

  • 否:实现 XY 使用 ABC 来格式化数字
  • 是的:所有其他(例如 iostream)我知道的实现(X、Y、Z)也将数字格式转发到 stdio,因为 ...

请避免过度投机的答案。

【问题讨论】:

  • 这取决于实现。你怎么能期待一个结论性的答案,例如“是的,他们都这样做”?
  • 所有内容都非常非常广泛,很难正确回答:可能总有一个陈述不成立。我更喜欢“所有其他我知道”的表述。
  • 如果他们这样做了,我一点也不感到惊讶;格式化double 比乍一看要难得多。我这样说是因为我知道 Tcl(好吧,不是 C++)现在在正常情况下不会为此使用 sprintf(),并且需要大量代码(包括完整的多精度算术库)来进行更改.
  • 有趣——这个问题是否广泛且难以正确回答取决于实际答案是什么。如果您碰巧知道一个反例,回答“否”很容易,回答“是”要么非常困难(涵盖所有重要的实现以及所有第三方字符串格式化库),要么非常主观,因为它取决于您碰巧知道哪些实现。
  • @sehe:是的,我认为您的回答证实了这是一个真实的问题。人们投票关闭的经典示例,因为他们不知道答案,因此假设无法回答,尽管这次有一些哲学基础;-)

标签: c++ formatting string-formatting iostream fastformat


【解决方案1】:

Boost Spirit 不使用 *printf,从代码(real.hppint.hpp)和基准测试中可以看出,例如整数和双精度数。

基准测试将 Boost Spirit Karma 的生成器与 Boost.Format 与 sprintf 和 std::stringstream 进行对比。只有 gcc 编译器的 sprintf 性能在该基准测试中才能接近。否则,Boost Spirit 无疑是赢家。

【讨论】:

    【解决方案2】:

    不,例如the {fmt} library 有自己的整数和浮点格式实现,这比sprintf 的常见实现快得多。以下是一个平台上的双字符串格式化基准 (dtoa-benchmark) 的结果:

    如您所见,{fmt} 比此处的 sprintf 快约 20 倍。

    整数格式为 also faster,但没有那么显着(在 Linux 和 macOS 上高达 6-7 倍):

    免责声明:我是 {fmt} 的作者。

    【讨论】:

    • 链接非常感谢。一个简单的问题(让我对 FastFormat 感到厌烦的一点):你在同一个模块中支持 wchar_t 和 char 字符串吗?它们是如何处理的?
    • @MartinBa:目前该库仅支持 char 字符串,但通过参数化字符类型也应该相对容易处理 wchar_t,类似于使用 std::basic_string 的方式。我计划很快添加这个功能。或者你的意思是你想在格式化过程中混合 char 和 wchar_t 字符串,比如 Format("{0}")
    • 不,我不是说混合在同一个表达式中——虽然它可能很好,但它唤醒了编码恶魔:-)——只是简单地支持 char 和 wchar_t 就像 std iostreams .
    • 现在完全支持 wchar_t 字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多