Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么打印0(零)时没有前导“;0x";使用C printf格式";%#x";?_C_Hex_Printf - Fatal编程技术网

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

为什么打印0(零)时没有前导“;0x";使用C printf格式";%#x";?,c,hex,printf,C,Hex,Printf,背景:我有很多脚本,它们通过查找前导“0x”来解析日志文件,查找十六进制数。我们的嵌入式C库更改为新的printf。新的printf比以前的printf更符合标准,我的脚本也坏了 在Linux机箱上: #include <stdio.h> int main( void ) { printf( "%#010x\n", 0 ); printf( "%#010x\n", 1 ); return 0; } 我们firmwware上的输出为: 0x00000000 0

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

在Linux机箱上:

#include <stdio.h>
int main( void )
{
    printf( "%#010x\n", 0 );
    printf( "%#010x\n", 1 );
    return 0;
}
我们firmwware上的输出为:

0x00000000
0x00000001
从printf(3)中,在“#”标志字符上: 对于x和x转换,非零结果前面有字符串“0x”(对于x转换为“0x”)


我很好奇为什么。如果不深入阅读C标准文件或为标准委员会成员购买午餐,为什么不在零值论点上使用前导0x?

标准似乎是这样写的:

  • %#x
    %#o
    尝试使用
    strtol
    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
来执行所需操作。

胡乱猜测:0是0,不考虑基数,因此无需指定它。值得注意的是,通过编写
“0x%08x”
,您可以获得始终包含前导
0x
的行为,然而,从总是包含前导的
0x
的库中获取所描述的标准行为将更为棘手。也许标准委员会正在优化一个更难获得的案例,而不是一个绝对最常见的案例?(当然,你不能将
“%#10x”
更改为
“0x%8x”
,但是,很难想象有人希望看到
0x0
,而不使用零填充。)(HTML)或(PDF)中没有提到这一点。在发布答案后,我注意到@ruakh已经在评论中给出了基本相同的信息。抱歉。没有必要道歉。答案比评论好。我把我的想法作为评论,而不是回答,因为我知道它们不可能是完整的;但是你的回答要彻底得多,而且很有意义。谢谢你的回答和评论!与strtol兼容的想法是有道理的。现在,我需要将大量代码更改为0x%08x。为什么
1
也没有这种行为?它与
0
一样明确。不需要添加额外的
0x
0x00000000
0x00000001