【问题标题】:Why do Boost Format and printf behave differently on same format string为什么 Boost Format 和 printf 在相同的格式字符串上表现不同
【发布时间】:2016-02-22 17:22:29
【问题描述】:

The Boost Format documentation 说:

它的一个目标是提供 printf 的替代品,这意味着 format 可以解析为 printf 设计的格式字符串,将其应用于 给定参数,并产生与 printf 相同的结果。

当我使用相同的格式字符串比较 boost:format 和 printf 的输出时,我得到不同的输出。网上例子是here

#include <iostream>
#include <boost/format.hpp>

int main()
{
    boost::format f("BoostFormat:%d:%X:%c:%d");

    unsigned char cr =65; //'A'
    int cr2i = int(cr);

    f % cr % cr % cr % cr2i;

    std::cout << f << std::endl;
    printf("Printf:%d:%X:%c:%d",cr,cr,cr,cr2i);
}

输出是:

BoostFormat:A:A:A:65

printf:65:41:A:65

不同之处在于我想将 char 显示为整数类型。

为什么会有差异?这是错误还是需要的行为?

【问题讨论】:

    标签: c++ c boost printf boost-format


    【解决方案1】:

    这是预期的行为。

    boost manual 中,写的是您使用的经典类型规范:

    但是 printf 的经典类型规范标志较弱 格式上的意思。它只是在 内部流和/或格式化参数,但不需要 对应的参数是特定类型。

    另请注意,在 stdlib-printf 调用中,所有 char 参数都是自动的 由于可变参数调用,转换为 int。所以生成的代码等同于:

    printf("Printf:%d:%X:%c:%d",cr2i,cr2i,cr2i,cr2i);
    

    % 运算符不进行这种自动转换。

    【讨论】:

    • +1 但是,哇,这太可怕了。我想知道他们这样做的理由是什么?似乎他们采用了 C 风格的格式(一开始并不好),但仍然没有使其向后兼容。就像两全其美。
    • 感谢您的回答。很高兴知道这是预期的行为,但这不是我所期望的。在这里,实际类型优先于说明符。所以对于 char 来说,'%d' 和 '%c' 没有区别,奇怪
    • @user694733:Boost.Format 无法根据格式字符串的(运行时)内容更改operator% 的(编译时)重载。现在您可以隐藏问题,但这确实增加了很大的复杂性 - 您必须在编译时实现 possible 重载方案,并在运行时选择正确的方案。这也不节省空间。
    • @joefel 在您的代码中,您实际上并没有编写与您想要输出的行为相匹配的代码。如果你想匹配 printf 行为,你应该写的是f % +cr % +cr % cr % +cr;
    • 这是使用一元 + 运算符来执行积分提升 - 详情请参阅 msdn.microsoft.com/en-us/library/ewkkxkwb(d=hv.2,v=vs.140).aspx
    【解决方案2】:

    除了the accepted answer

    wchar_t 以及 unsigned short 和其他等效类型的参数也会发生这种情况,例如,当在 Windows API 中使用结构成员时(例如,SYSTEMTIME),这可能是意料之外的。由于历史原因,它们是 WORD 类型的短整数。

    如果您在旧代码中使用 Boost 格式来替代 printf 和“类似 printf”的函数,您可以考虑创建一个包装器,它会覆盖 % 运算符,从而进行转换

    • charshortint
    • unsigned charunsigned shortunsigned int

    模拟 C 变量参数列表的行为。它仍然不会 100% 兼容,但大多数剩余的不兼容实际上有助于修复潜在的不安全代码。

    较新的代码可能不应该使用 Boost 格式,而是 standard std::format,它与 printf 不兼容。

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多