为什么打印0(零)而没有使用C打印格式“%#x”的前导“0x”?

背景:我有许多脚本通过查找前导“0x”来解析查找hex数的日志文件。 我们的嵌入式C库改为新的printf。 新的printf比我们之前更符合标准,我的脚本破了。

在Linux机器上:

#include  int main( void ) { printf( "%#010x\n", 0 ); printf( "%#010x\n", 1 ); return 0; } 

输出(使用glibc)是:

 0000000000 0x00000001 

我们公司的输出是:

 0x00000000 0x00000001 

从printf(3)开始,在’#’标志字符上:“对于x和X转换,非零结果的前缀为字符串”0x“(或X转换为”0X“)。”

我很好奇为什么 。 如果没有挖掘C标准文件或为标准委员会成员购买午餐,为什么不在零价值论证中使用前导0x?

标准似乎是这样编写的:

  • %#x%#o尝试保证使用strtol with base = 0正确解析输出。

  • 在这些情况下, #标志会添加尽可能少的额外字符 。 例如,0打印为0因为不需要添加额外的0x 。 如果指定最小字段宽度和0填充,这很有意义。

  • 如果你想总是添加0x ,你通常可以简单地写一些像0x%x东西。 因此%#x似乎在那些你真正想要特殊处理0的特殊情况下才有用。但0x的预挂起对默认字段宽度说明符不起作用,例如) 0x%12x是右对齐的通过0x和hex数字之间的空白,在这种情况下不太可能是想要的。 对于这种情况,需要使用sprintf进行额外的准备传递,因此像"0x2ac2"这样的hex字符串可以是白色空格右对齐,例如printf( "%12s", hexstr); 幸运的是,使用类似printf( "0x%012x", hexstr);东西来certificate0而不是空格printf( "0x%012x", hexstr); 按预期工作,为解析器生成有效的hex数字。

现在,指定%#x工作的方式在隔离方面很有意义。 像%010x这样的工作方式可以%010x使用。 你正在组合这两个修饰符,最终的结果可能是奇怪的。 对于另一个应用程序,比如自动生成整齐的C代码来初始化表,有0,而不是0x0不是问题。

但是没有必要将%#x%010x结合起来。 你可以写0x%08x来做你想要的。