printf()和scanf()都可以用*修饰符来修改转换说明的含义,但是他们的用法又不一样。
首先来讨论printf()函数的*修饰符的用法。
如果你不想预先设定字段宽度,希望通过程序来设定,那么*修饰符就会派上用场。*修饰符不能直接使用,还是要用一个参数来告诉函数,字段宽度究竟是多少。也就是说,转换说明 %*d ,参数列表中一定要有 * 和 d 的对应值。浮点型也一样。
下面来看程序varwid.c所展示的用法
#include <stdio.h>
int main (void)
{
unsigned width, precision;
int number = 256;
double weight = 250.41;
printf("Enter a field width:\n");
scanf("%d",&width);
printf("The number is :%*d\n", width, number);//红字1
printf("Now enter a width and a precision:\n");
scanf("%d %d", &width, &precision);
printf("Weight = %*.*f\n", width, precision, weight);//红字2
printf("Done!\n");
return 0;
}
运行是这样的:
Enter a field width:
6
The number is : 256
Now enter a width and a precision:
8 3
Weight = 250.410
Done!
程序中(红字1)变量width提供字段宽度,number提供待打印数字。printf参数列表中有两个参数width在number前面,因为转换说明中 * 在 d 前面。同理(红字2)也是这样。
【注】“%*.*f”可能是有些同学产生疑惑,其实之前已经讲过 “ . ”左右两边分别是字段宽度和保留小数的位数,这个程序中是8和3分别表示字段宽度为8,保留三位小数。
scanf()函数中*的用法与printf()不同,把 * 放在%和转换字符之间时,会使得scanf()跳过相应的输出项。
下面来看程序skiptwo.c
#include <stdio.h>
int mian (void)
{
int n;
printf("Please enter three integers:\n");
scanf("%*d %*d %d", &n);
printf("The last integer was %d\n",n);
return 0;
}
可以看到
Please enter three integers:
123 456 789
The last integer was 789
输出结果如上,scanf()函数跳过了前两个输入的数。
在程序需要读取特定文件内容时,这项跳过功能会很有用。
printf的用法提示
想把数据打印成列,指定固定字段宽度很有用。因为默认字段宽度是待打印数字的宽度,如果同一列打印的数字位数不同,那么下面的语句:
printf("%d %d %d \n",n1,n2,n3);
打印出的结果可能参差不齐。
使用足够大的固定字段宽度可以让输出整齐美观,就像这样:
printf("%9d %9d %9d \n",n1,n2,n3);
在两个转换说明之间加入一个空白字符,可以确保即使一个数字溢出了自己的字段,下一个数字也不会紧跟着改数字一起输出( 这样两个数字看起来像一个数字)。这是因为格式字符串中的普通字符(包括空白字符)会打印出来。
另外,如果要在文字中嵌入一个数字,通常指定一个小于或等于该字段宽度的字段会比较方便,这样输出的字符宽度正合适,没有不必要的空白。