鉴于for的字符0x7f
是CTRL-?,它看起来像输出memblock[0]
字符而不是十六进制值,尽管你的格式字符串。
根据我在文档中阅读的内容,这实际上是有道理的。Boost::format
是一个类型安全的库,其中格式说明符指示变量的输出方式,但受所述变量的实际类型的限制,该类型优先。
文档状态(我的粗体):
旧版 printf 格式字符串:格式规范在%spec
哪里。spec
printf
spec
传递格式化选项,如宽度、对齐方式、用于格式化数字的数字基数以及其他特定标志。但是经典的 type-specification flag 的格式printf
含义较弱。
它只是在内部流上设置适当的标志,和/或格式化参数,但不要求相应的参数是特定类型。例如:规范2$x
,对于 printf 来说,意思是“打印参数编号 2,它是一个整数,以十六进制表示”,仅表示“打印参数 2,流基域标志设置为十六进制”的格式。
据推测,当您打印 a 时,将字段标志设置为 hex 并没有多大意义char
,因此它被忽略了。另外来自该文档(虽然解释了一点):
type-char
不会将相关参数强制为一组受限制的类型,而只是设置与此类型规范相关联的标志。A type-char
of p
orx
表示十六进制输出,但只是在流上设置十六进制标志。
此链接中的文本也更具体地验证了这一点:
但是,我和我的同事发现,当使用%d
描述符打印char
变量时,结果就像%c
使用了描述符一样——printf
并且boost::format
不会产生相同的结果。
上面链接的 Boost 文档还解释了零填充0
修饰符适用于所有类型,而不仅仅是整数类型,这就是为什么你得到第二个0
(0x0^?
是^?
单个字符)。
在许多方面,这类似于尝试const char *
在 C++ 中输出 a 以便您看到指针的问题。以下代码:
#include <iostream>
int main() {
const char *xyzzy = "plugh";
std::cout << xyzzy << '\n';
std::cout << (void*)xyzzy << '\n';
return 0;
}
会产生类似的东西:
plugh
0x4009a0
因为标准库知道 C 风格的字符串是一种特殊情况,但是如果你告诉它们它是一个 void 指针,它们会给你一个指针作为输出。
在您的特定情况下的解决方案可能只是将您转换为智能处理格式说明符char
的一种int
或其他类型:%x
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));