简体   繁体   English

boost :: format hex中的奇怪行为

[英]Odd behavior in boost::format hex

I'm trying to format a binary array: char* memblock to a hex string. 我正在尝试将二进制数组格式化: char* memblock为十六进制字符串。

When I use the following: 当我使用以下内容时:

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

I get the following output: 我得到以下输出:

0x7f,

When I try to use boost::format on an ofstream like so: 当我尝试在ofstream上使用boost::format时:

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

I get a weird output like this (seen in Vi): 0x0^? 我得到一个像这样的奇怪输出(在Vi中看到): 0x0^? .

What gives? 是什么赋予了?

Given that the character for 0x7f is CTRL-? 鉴于0x7f字符CTRL-? , it looks like it's outputting the memblock[0] as a character rather than a hex value, despite your format string. ,看起来它输出的是memblock[0]作为字符而不是十六进制值,尽管你的格式字符串。

This actually makes sense based on what I've read in the documentation. 根据我在文档中读到的内容,这实际上是有意义的。 Boost::format is a type-safe library where the format specifiers dictate how a variable will be output, but limited by the actual type of said variable, which takes precedence. Boost::format是一个类型安全的库,其中格式说明符指示如何输出变量, 但受所述变量的实际类型的限制,该变量优先。

The documentation states (my bold): 文档说明(我的粗体):

Legacy printf format strings: %spec where spec is a printf format specification. 旧版printf格式字符串: %spec其中specprintf格式规范。

spec passes formatting options, like width, alignment, numerical base used for formatting numbers, as well as other specific flags. spec传递格式化选项,如宽度,对齐方式,用于格式化数字的数字基数,以及其他特定标志。 But the classical type-specification flag of printf has a weaker meaning in format. 但是printf的经典类型规范标志在格式上具有较弱的含义

It merely sets the appropriate flags on the internal stream, and/or formatting parameters, but does not require the corresponding argument to be of a specific type. 它仅在内部流和/或格式化参数上设置适当的标志 ,但不要求相应的参数具有特定类型。 eg : the specification 2$x , meaning "print argument number 2, which is an integral number, in hexa" for printf, merely means "print argument 2 with stream basefield flags set to hex" for format. 例如:规范2$x ,意思是“打印参数编号2,这是一个整数,以六进制”表示printf,仅表示“打印参数2,流基础域标志设置为十六进制”,用于格式。

And presumably, having the field flag set to hex doesn't make a lot of sense when you're printing a char , so it's ignored. 并且假设将字段标志设置为十六进制在打印char时没有多大意义,所以它被忽略了。 Additionally from that documentation (though paraphrased a little): 此外,该文件(虽然转述一点):

The type-char does not impose the concerned argument to be of a restricted set of types, but merely sets the flags that are associated with this type specification. type-char不会将相关参数强加为一组受限制的类型,而只是设置与此类型规范关联的标志 A type-char of p or x means hexadecimal output but simply sets the hex flag on the stream. px type-char表示十六进制输出,但只是在流上设置十六进制标志。

This is also verified more specifically by the text from this link : 链接中的文字也更具体地验证了这一点

My colleagues and I have found, though, that when a %d descriptor is used to print a char variable the result is as though a %c descriptor had been used - printf and boost::format don't produce the same result. 我的同事和我发现,当使用%d描述符打印char变量时,结果就好像使用了%c描述符 - printfboost::format不会产生相同的结果。

The Boost documentation linked to above also explains that the zero-padding 0 modifier works on all types, not just integral ones, which is why you're getting the second 0 in 0x0^? 上面链接的Boost文档还解释了零填充0修饰符适用于所有类型,而不仅仅是整数类型,这就是为什么你在0x0^?得到第二个0 0x0^? (the ^? is a single character). ^?单个字符)。


In many ways, this is similar to the problem of trying to output a const char * in C++ so that you see a pointer. 在许多方面,这类似于尝试在C ++中输出const char *以便您看到指针的问题。 The following code: 以下代码:

#include <iostream>
int main() {
   const char *xyzzy = "plugh";
   std::cout << xyzzy << '\n';
   std::cout << (void*)xyzzy << '\n';
   return 0;
}

will produce something like: 会产生类似的东西:

plugh
0x4009a0

because the standard libraries know that C-style strings are a special case but, if you tell them it's a void pointer, they'll give you a pointer as output. 因为标准库知道C风格的字符串是一种特殊情况但是,如果你告诉它们它是一个无效指针,它们会给你一个指针作为输出。

A solution in your specific case may be just to cast your char to an int or some other type that intelligently handles the %x format specifier: 您的特定情况下,解决方案可能只是将您的char转换为int或其他智能处理%x格式说明符的类型:

outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM