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

时间:2011-12-14 23:24:26

标签: c hex printf

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

在Linux机上:

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

输出(使用glibc)是:

0000000000
0x00000001

我们的firmwware的输出是:

0x00000000
0x00000001

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

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

1 个答案:

答案 0 :(得分:24)

标准似乎是这样写的:

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

  • 在这些情况下,#标志会将添加为可能的额外字符。例如,0打印为0,因为无需添加额外的0x。如果你 not 指定最小字段宽度和0-padding,这很有意义。

  • 如果您想要始终添加0x,您通常可以简单地编写0x%x之类的内容。因此%#x在您真正想要特殊处理0的特殊情况下似乎只有 。但{{1}的预先处理使用默认字段宽度说明符不能很好地工作,例如,0x由0x和十六进制数字之间的空白右对齐,这在这种情况下不太可能是想要的。对于这种情况,需要使用sprintf进行额外的准备传递,因此像0x%12x这样的十六进制字符串可以是空格右对齐,例如"0x2ac2"幸运的是使用printf( "%12s", hexstr);来证明是正确的,而不是使用某些空格像0一样按预期工作,为解析器生成有效的十六进制数字。

现在printf( "0x%012x", hexstr);指定工作的方式在隔离方面很有意义。像%#x这样的工作方式可以单独使用。你正在组合这两个修饰语,最终结果可能是奇怪的。对于另一个应用程序,例如自动生成用于初始化表的简洁C代码,使用%010x而不是0,不是问题。

但无需合并0x0%#x。你可以写%010x来做你想做的事。

相关问题