boost::format 十六进制的奇怪行为
Odd behavior in boost::format hex
我正在尝试格式化二进制数组:char* memblock
为十六进制字符串。
当我使用以下内容时:
fprintf(out, "0x%02x,", memblock[0]);
我得到以下输出:
0x7f,
当我尝试像这样在 ofstream 上使用 boost::format
时:
std::ofstream outFile (path, std::ios::out); //also tried with binary
outFile << (boost::format("0x%02x")%memblock[0]);
我得到了这样一个奇怪的输出(在 Vi 中看到):0x0^?
.
什么给了?
假设0x7f
的字符是CTRL-?,看起来它正在输出memblock[0]
作为一个字符而不是一个十六进制值,尽管你的格式字符串。
根据我在文档中阅读的内容,这实际上是有道理的。 Boost::format
是一个类型安全的库,其中格式说明符指定变量的输出方式,但受所述变量的实际类型限制, 优先。
documentation 状态(我的粗体):
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.
大概,当您打印 char
时,将字段标志设置为十六进制没有多大意义,因此它被忽略了。另外从该文档(虽然解释了一点):
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.
中的文字也更具体地验证了这一点
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.
上面链接的 Boost 文档还解释了零填充 0
修饰符适用于 所有 类型,而不仅仅是整数类型,这就是为什么你在 0x0^?
中获取第二个 0
(^?
是一个 单个 字符)。
在很多方面,这类似于试图在 C++ 中输出一个 const char *
以便您看到一个 指针的问题。 下面的代码:
#include <iostream>
int main() {
const char *xyzzy = "plugh";
std::cout << xyzzy << '\n';
std::cout << (void*)xyzzy << '\n';
return 0;
}
会产生类似的东西:
plugh
0x4009a0
因为标准库知道 C 风格的字符串是一种特殊情况,但是如果您告诉它们是一个空指针,它们会给您一个指针作为输出。
您的 特定情况下的解决方案可能只是将您的 char
转换为 int
或智能处理 %x
格式说明符:
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));
我正在尝试格式化二进制数组:char* memblock
为十六进制字符串。
当我使用以下内容时:
fprintf(out, "0x%02x,", memblock[0]);
我得到以下输出:
0x7f,
当我尝试像这样在 ofstream 上使用 boost::format
时:
std::ofstream outFile (path, std::ios::out); //also tried with binary
outFile << (boost::format("0x%02x")%memblock[0]);
我得到了这样一个奇怪的输出(在 Vi 中看到):0x0^?
.
什么给了?
假设0x7f
的字符是CTRL-?,看起来它正在输出memblock[0]
作为一个字符而不是一个十六进制值,尽管你的格式字符串。
根据我在文档中阅读的内容,这实际上是有道理的。 Boost::format
是一个类型安全的库,其中格式说明符指定变量的输出方式,但受所述变量的实际类型限制, 优先。
documentation 状态(我的粗体):
Legacy printf format strings:
%spec
wherespec
is aprintf
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 ofprintf
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.
大概,当您打印 char
时,将字段标志设置为十六进制没有多大意义,因此它被忽略了。另外从该文档(虽然解释了一点):
中的文字也更具体地验证了这一点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. Atype-char
ofp
orx
means hexadecimal output but simply sets the hex flag on the stream.
My colleagues and I have found, though, that when a
%d
descriptor is used to print achar
variable the result is as though a%c
descriptor had been used -printf
andboost::format
don't produce the same result.
上面链接的 Boost 文档还解释了零填充 0
修饰符适用于 所有 类型,而不仅仅是整数类型,这就是为什么你在 0x0^?
中获取第二个 0
(^?
是一个 单个 字符)。
在很多方面,这类似于试图在 C++ 中输出一个 const char *
以便您看到一个 指针的问题。 下面的代码:
#include <iostream>
int main() {
const char *xyzzy = "plugh";
std::cout << xyzzy << '\n';
std::cout << (void*)xyzzy << '\n';
return 0;
}
会产生类似的东西:
plugh
0x4009a0
因为标准库知道 C 风格的字符串是一种特殊情况,但是如果您告诉它们是一个空指针,它们会给您一个指针作为输出。
您的 特定情况下的解决方案可能只是将您的 char
转换为 int
或智能处理 %x
格式说明符:
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));