本文介绍了为什么打印0(零)时不带前导"0x"?带有C printf格式“%#x"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Background: I have a number of scripts that parse log files looking for hex numbers by finding the leading "0x". Our embedded C library changed to a new printf. The new printf is more standards compliant than our previous and my scripts broke.

在Linux机器上:

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

输出(使用glibc)是:

Output (using glibc) is:

0000000000
0x00000001

我们固件上的输出是:

0x00000000
0x00000001

在printf(3)中,使用'#'标志字符:对于x和X转换,在非零结果前添加字符串"0x"(对于X转换,则为字符串"0X")."

From printf(3), on the '#' flag character:"For x and X conversions, a nonzero result has the string "0x" (or "0X" for X conversions) prepended to it."

我很好奇为什么.如果不深入研究C标准文档或为标准委员会成员买午餐,为什么不对零值参数使用前导0x?

I'm curious why. Without digging through the C standards documents or buying lunch for standards committee members, why not a leading 0x on a zero valued argument?

推荐答案

标准似乎是这样写的:

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

  • %#x and %#o try to guarantee that the output can be parsed correctly using strtol with base = 0.

在这些情况下,#标志添加尽可能少的额外字符.例如,将0打印为0,因为不需要添加多余的0x.如果您指定最小字段宽度和0-padding,这很有意义.

In these cases, the # flag adds as few extra characters as possible. For example, 0 is printed as 0 because there is no need to add the extra 0x. This makes a lot of sense if you do not specify the minimum field width and 0-padding.

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

If you wanted to add 0x always, you could often simply write something like 0x%x. Hence %#x would seem to be useful only in those special cases in which you really want the special handling of 0. But the pre-pending of 0x doesn't work well with default field width specifiers eg) 0x%12xis right justified by blanks between the 0x and hex digits, which is unlikely to be what's wanted in that case. For this case an extra preparatory pass with sprintf would be required, so a hex string like "0x2ac2" can be white space right justified with something like printf( "%12s", hexstr); Fortunately justifying with 0 rather than spaces using something like printf( "0x%012x", hexstr); works as expected producing valid hex digits for a parser.

现在,指定%#x的工作方式在隔离时很有意义.像%010x这样的工作方式被指定为孤立地工作,这很有意义.您将这两个修饰符组合在一起,最终结果可能会很奇怪.对于另一个应用程序,例如自动生成纯净的C代码以初始化表,使用0,而不是0x0并不是问题.

Now the way %#x is specified to work makes a lot of sense in isolation. And the way something like %010x is specified to work makes a lot of sense in isolation. You are combining these two modifiers, and the end result is, arguably, strange. For another application, like auto generating neat C code to initialise tables, having 0, rather than 0x0 is not an issue.

但是没有必要组合%#x%010x.您可以编写0x%08x做您想做的事.

But there is no need to combine %#x and %010x. You could just write 0x%08x to do what you want.

这篇关于为什么打印0(零)时不带前导"0x"?带有C printf格式“%#x"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 00:55