Given that the character for 0x7f
is CTRL-?, it looks like it's outputting the memblock[0]
as a character rather than a hex value, despite your format string.
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.
The documentation states (my bold):
Legacy printf format strings: %spec
where spec
is a printf
format specification.
spec
passes formatting options, like width, alignment, numerical base used for formatting numbers, as well as other specific flags. But the classical type-specification flag of printf
has a weaker meaning in format.
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. e.g. : 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.
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. 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. A type-char
of p
or x
means hexadecimal output but simply sets the hex flag on the stream.
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.
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^?
(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. 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.
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:
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));