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

Dav*_*ole 28 c printf hex

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

在Linux机器上:

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

输出(使用glibc)是:

0000000000
0x00000001
Run Code Online (Sandbox Code Playgroud)

我们公司的输出是:

0x00000000
0x00000001
Run Code Online (Sandbox Code Playgroud)

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

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

Juk*_*ela 24

标准似乎是这样编写的:

  • %#x%#o尝试保证可以使用strtolwith 正确解析输出base = 0.

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

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

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

但也没有必要合并%#x%010x.你可以写信0x%08x去做你想做的事.

  • 为什么`1`也没有这种行为?它与"0"一样明确.没有必要添加额外的"0x". (7认同)
  • +1.没有必要道歉.答案比评论更好.我发表了自己的想法作为评论,而不是答案,因为我知道他们不能完整; 但你的答案要彻底得多,而且很有意义. (6认同)