3

我正在尝试将二进制数组:格式化为char* memblock十六进制字符串。

当我使用以下内容时:

fprintf(out, "0x%02x,", memblock[0]);

我得到以下输出:

0x7f,

当我尝试boost::format像这样在 ofstream 上使用时:

std::ofstream outFile (path, std::ios::out); //also tried with binary
outFile << (boost::format("0x%02x")%memblock[0]);

我得到一个像这样的奇怪输出(在 Vi 中看到)0x0^?:.

是什么赋予了?

4

1 回答 1

8

鉴于for的字符0x7fCTRL-?,它看起来像输出memblock[0]字符而不是十六进制值,尽管你的格式字符串。

根据我在文档中阅读的内容,这实际上是有道理的。Boost::format是一个类型安全的库,其中格式说明符指示变量的输出方式,但受所述变量的实际类型的限制,该类型优先。

文档状态(我的粗体):

旧版 printf 格式字符串:格式规范在%spec哪里。specprintf

spec传递格式化选项,如宽度、对齐方式、用于格式化数字的数字基数以及其他特定标志。但是经典的 type-specification flag 的格式printf含义较弱

它只是在内部流上设置适当的标志,和/或格式化参数,但不要求相应的参数是特定类型。例如:规范2$x,对于 printf 来说,意思是“打印参数编号 2,它是一个整数,以十六进制表示”,仅表示“打印参数 2,流基域标志设置为十六进制”的格式。

据推测,当您打印 a 时,将字段标志设置为 hex 并没有多大意义char,因此它被忽略了。另外来自该文档(虽然解释了一点):

type-char不会将相关参数强制为一组受限制的类型,而只是设置与此类型规范相关联的标志。A type-charof porx表示十六进制输出,但只是在流上设置十六进制标志。

此链接中的文本也更具体地验证了这一点:

但是,我和我的同事发现,当使用%d描述符打印char变量时,结果就像%c使用了描述符一样——printf并且boost::format不会产生相同的结果。

上面链接的 Boost 文档还解释了零填充0修饰符适用于所有类型,而不仅仅是整数类型,这就是为什么你得到第二个00x0^?^?单个字符)。


在许多方面,这类似于尝试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]));
于 2015-01-19T05:24:50.777 回答