%*。* d如何在printf()中工作?

时间:2013-07-10 09:20:43

标签: c++ c printf

#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?

3 个答案:

答案 0 :(得分:8)

*之前的.的参数是字段宽度,而*之后的.的参数是< EM>精度

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

另一方面,

精度具有根据正在执行的转换而变化的含义。消极精度被视为根本没有指定精度。对于整数,它是要生成的位数(不是总输出)的最小数量;如果生成的数字较少,则向左添加零。显式精度为0会导致在值为0时不生成数字(而不是生成单个0)。对于字符串,精度限制输出字节数,必要时截断字符串(并允许更长,非空终止的输入数组)。对于浮点说明符,精度控制打印的位数,在小数点后(对于%f)或总有效位置(对于其他格式)。

在您的示例中:

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

此处字段左对齐(右边填充),最小宽度为6,但字段最终会变宽,因此忽略宽度。 7的精度强制整数输出至少为7位,因此最终以0020000作为已转换的字段内容,已超出宽度。

在另一个:

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

字段宽度为5,默认右对齐;填充左侧有空格。否定精度被忽略,就好像没有指定一样,因此转换后的字段内容为2000,只有4个字节,最多填充5个字节以通过单个前导空格填充宽度。

答案 1 :(得分:3)

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

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

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

答案 2 :(得分: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;
}