为什么提升:格式和printf在相同的格式字符串

时间:2015-11-20 09:20:59

标签: c++ c boost boost-format

The Boost Format documentatio n说:

  

其目标之一是为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显示为整数类型。

为什么会有区别?这是一个错误或想要的行为吗?

2 个答案:

答案 0 :(得分:4)

这是预期的行为。

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

  

但是printf的经典类型规范标志较弱   格式含义。它只是在上面设置了适当的标志   内部流和/或格式化参数,但不需要   相应的参数属于特定类型。

另请注意,在stdlib-printf调用中,所有char参数都是自动的 由于vararg调用而转换为int。因此生成的代码与:

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

此自动转换不是使用%运算符完成的。

答案 1 :(得分:0)

添加到the accepted answer

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

如果您使用 Boost Format 作为旧代码中 WORD 和“printf-like”函数的替代品,您可以考虑创建一个包装器,它以这样的方式覆盖 printf 运算符它转换

  • %charshort
  • intunsigned charunsigned short

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

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