为什么 Boost 格式和 printf 在同一格式字符串上的行为不同
Why do Boost Format and printf behave differently on same format string
Boost Format 文档说:
它的目标之一是提供printf的替代品,这意味着 格式可以解析为 printf 设计的格式字符串,将其应用于 给定参数,并产生与 printf 相同的结果。
当我使用相同的格式字符串比较 boost:format 和 printf 的输出时,我得到了不同的输出。在线示例在这里
#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);
}
输出为:
增强格式: A:A:A:65
打印: 65:41:A:65
区别在于当我想将字符显示为整数类型时。
为什么会有区别?这是错误还是想要的行为?
预期行为。
在提升手册中,它写了你使用的经典类型规范:
但是 printf 的经典类型规范标志较弱 格式的含义。它只是在 内部流和/或格式化参数,但不需要 要具有特定类型的相应参数。
另请注意,在 stdlib-printf 调用中,所有char
参数都是自动的。由于 vararg-call 而转换为 int
。因此,生成的代码与以下内容相同:
printf("Printf:%d:%X:%c:%d",cr2i,cr2i,cr2i,cr2i);
此自动转换不是使用 %
运算符完成的。
对接受答案的补充:
这也发生在类型 wchar_t
以及 unsigned short
和其他等效类型的参数上,这可能是意外的,例如,在 Windows API 中使用结构的成员(例如,SYSTEMTIME
(时,由于历史原因,它们是 WORD
类型的短整数。
如果您使用Boost Format来替代遗留代码中的printf
和"类似printf"的函数,则可以考虑创建一个包装器,该包装器以转换的方式覆盖%
运算符
-
char
和short
int
-
unsigned char
和unsigned short
unsigned int
以模拟 C 变量参数列表的行为。它仍然不是100%兼容的,但大多数剩余的不兼容实际上有助于修复潜在的不安全代码。
较新的代码可能不应该使用Boost格式,而是使用标准std::format
,这与printf
不兼容。
- 是否可以从格式字符串中检索"width"
- 我应该如何从 stdin C++ 中读取可变长度的格式字符串?
- 从用户定义的类生成格式字符串?
- 如何连接格式字符串?
- 如何在C++中将"%Y%m%d"格式字符串转换为time_t变量?
- CPPCHECK C++成员函数上的格式字符串
- scanf() 语句中"%*[^n]"的格式字符串指示什么?分配抑制器 (*) 和否定扫描集 ([^) 如何协同工作?
- 自定义 {fmt} 格式化函数,具有编译时格式字符串检查功能
- '|' scanf 格式字符串是什么意思
- 如何使用 msgfmt 验证格式字符串中的位置表示法占位符
- sscanf_s:格式字符串"%d"需要类型为"int *"的参数,但可变参数 4 的类型为"WORD *"
- C4477: 'fprintf' :格式字符串 '%s' 需要类型为"char *"的参数,但可变参数 1 的类型为"int *"
- 如何使用OpenSSL API从其PEM格式字符串中读取RSA公钥
- C 格式字符串宏
- C++等效于 C 的格式字符串
- 如何使用 C++ 中的 rapidjson 库从 json 格式字符串中获取值
- _vsnprintf和_vsnprintf_s的格式字符串中的可用百分比字符
- 如何将格式字符串发送到iostream
- 跨平台格式字符串
- 使用 swprintf() 打印"0x0"的格式字符串应该是什么?