6
#include <stdio.h>

int main()
{
  printf("%*.*d\n", -6 , 7,20000);
  printf("%*.*d\n", 5, -6, 2000);
  return 0;
}

输出:

0020000
 2000

我不明白如何printf解释格式说明符* 。* ?

在第一次调用时printf(),后面的7会覆盖前面的-6吗?这样输出宽度的大小变成了7?

4

3 回答 3

8

*before 的参数.字段宽度*after 的参数.精度

字段宽度是将作为转换结果输出的最小字节数;如果产生的字节数更少,输出将被填充(默认情况下,在左边有空格,但左零填充和右空格填充也是选项,由标志控制)。for 宽度的负参数*被解释为带有标志的相应正值-,它将填充向右移动(即左对齐字段)。

另一方面,精度的含义会根据所执行的转换而有所不同。负精度被视为根本没有指定精度。对于整数,它是要产生的最小位数(不是总输出);如果产生的数字较少,则在左侧添加零。当值为 0 时,显式精度为 0 会导致不生成任何数字(而不是生成单个数字0)。对于字符串,精度限制输出字节数,必要时截断字符串(并允许更长的、非空终止的输入数组)。对于浮点说明符,精度控制打印的位数,无论是在小数点之后(对于%f) 或总重要位置(对于其他格式)。

在您的示例中:

printf("%*.*d\n", -6 , 7,20000);

这里字段左对齐(右侧填充),最小宽度为 6,但字段最终会变宽,因此忽略宽度。7 的精度强制整数输出至少为 7 位,因此您最终0020000会得到已超过宽度的转换后的字段内容。

在另一个:

printf("%*.*d\n", 5, -6, 2000);

字段宽度为5,默认右对齐;padding 在左边有空格。负精度被忽略,就好像它没有被指定一样,所以转换后的字段内容2000只有 4 个字节,通过单个前导空格填充到 5 个字节以填充宽度。

于 2013-07-10T09:26:29.950 回答
3
printf("%*.*d\n", -6 , 7,20000); 

printf("%-6.7d\n, 20000);

这只是为动态格式提供了一种方式。

于 2013-07-10T09:22:44.873 回答
0

这是 glibc 中 printf 的源代码

/* VARARGS1 */
int  __printf (const char *format, ...)
{
 va_list arg;
 int done;

 va_start (arg, format);
 done = vfprintf (stdout, format, arg);
 va_end (arg);

 return done;

}

如您所见, printf 从 va_list 获取参数

这是另一个示例,向您展示 printf 的工作原理:

/* va_start example */
#include <stdio.h>      /* printf */
#include <stdarg.h>     /* va_list, va_start, va_arg, va_end */

void PrintFloats (int n, ...)
{
  int i;
  double val;
  printf ("Printing floats:");
  va_list vl;
  va_start(vl,n);
  for (i=0;i<n;i++)
  {
    val=va_arg(vl,double);
    printf (" [%.2f]",val);
  }
  va_end(vl);
  printf ("\n");
}

int main ()
{
  PrintFloats (3,3.14159,2.71828,1.41421);
  return 0;
}
于 2013-07-10T13:53:26.007 回答