C printf 0标志和宽度属性与精度标志之间的区别

C printf difference between 0 flag & width attribute and precision flag

目前正在学习libc的printf功能,不懂,有什么区别:

printf("Test : %010d", 10);

使用 0 标志和 10 作为宽度说明符

printf("Test : %.10d", 10);

使用 10 作为精度说明符

产生相同的输出:Test : 0000000010

除了可能纯粹是概念上的区别外,没有其他区别。

在第一种情况下,您只是用完全独立的填充 0 字符填充空白区域。在第二种情况下,这些零是在转换参数值时创建的前导零。 (诚​​然,这是非常做作的。)

无论如何,这些零看起来、闻起来和嘎嘎叫都一样。


但是,在一般情况下,当精度与填充字段宽度的行为不同时,有一种模糊的特定情况:当您要求零字段宽度并打印零值时。当使用零 precision 时,根本不会打印零值。当使用零 field-width 时,零值将照常显示

printf("%00d\n", 0); // prints '0'
printf("%.0d\n", 0); // prints nothing

显然这也是一种非常人为的情况,因为在这种情况下不会发生填充。

在你的第二种情况下你可能期望 10.0000000000 - 但%d 仅适用于整数。规范说:

For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written.

(精度是以 . 开头的部分,因此在您的情况下 10 。)

因此,对于 %.10d,您至少指定了 10 位数字来表示两位数,因此它以 8 个前导零完成。

表示%010d%.10d会产生相同的结果。

我们将从 the docs for printf() 开始,我将突出显示它们的相关部分。

前 0 个填充。

`0' (zero)

Zero padding. For all conversions except n, the converted value is padded on the left with zeros rather than blanks. If a precision is given with a numeric conversion (d, i, o, u, i, x, and X), the 0 flag is ignored.

然后是精度。

An optional precision, in the form of a period . followed by an optional digit string. If the digit string is omitted, the precision is taken as zero. This gives the minimum number of digits to appear for d, i, o, u, x, and X conversions, the number of digits to appear after the decimal-point for a, A, e, E, f, and F conversions, the maximum number of significant digits for g and G conversions, or the maximum number of characters to be printed from a string for s conversions.

%010d 表示将零填充到最小宽度为 10 位数字。没问题。

%.10d",因为您使用的是 %d,表示要出现的最小位数是 10。因此与零填充相同。 %.10f 会更像您预期的那样。

我建议您使用 %010d 来补零。 %.10d 形式是一个令人惊讶的特性,可能会使读者感到困惑。我不知道它,我很惊讶它没有被简单地忽略。

两种格式对正数产生相同的输出,但对大于 -1000000000:

的负数输出不同

printf("Test : %010d", -10); 产生 -000000010

printf("Test : %.10d", -10); 产生 -0000000010

格式 %010d 用前导零填充输出,最多 宽度 10 个字符。

格式 %.10d 用前导零填充转换后的数字,最多 10 .

如果您不想为值 0 产生任何输出,但在其他情况下产生像 %d:

这样的正常转换,则第二种形式很有用
printf("%.0d", 0);  // no output
printf("%.0d", 10);  // outputs 10

另请注意,第一种形式中的初始 0 是一个标志:它可以与其他标志以任何顺序组合,如 %0+10d 中产生 +000000010 并且它可以与间接宽度一起使用,如 printf("%0*d", 10, 10); 中产生 0000000010.