格式化输入输出

printf函数

转换说明

%m.pX, %-m.pX

最小栏宽m:要显示的最少字符的数量
  • 如果数值字符数少于m,右对齐——值前面有空格
  • 多于m,栏宽自动扩展为所需尺寸
  • 前面有个负号代表左对齐
精度p:依赖于转换指示符X的选择
指示符 含义
d 待显示数字的最少个数(默认p为1),如果数字数量小于p,前面补零,直到数量等于p
e 显示指数(科学计数法)的浮点数,p指明小数点后的数字个数(默认p为6)。
f 小数点后的数字个数(默认p为6)。
g 指数形式或定点十进制的浮点数(不用于整数)。p指明有效数字的最大数量。与f不同,不显示尾随的0,如果数值没有小数点后的数字,就不会显示小数点。
int a = 10;
printf("%3d\n", a);
printf("%.3d\n", a);
printf("%3.3d\n", a);
printf("%4.3d\n", a);

输出

 10
010
010
 010

先做精度,再做最小栏宽

转义序列

  • 警报符:\a 产生一声鸣响
  • 回退符:\b 光标从当前位置回退一个位置
  • 换行符:\n 光标跳到下一行的起始位置
  • 水平制表符:\t 光标移动到下一个制表符的位置,制表符一般占8列(距离由操作系统决定)
// 输入
printf("Item\tUnit\tPurchase\n\tPrice\tDate\n");
// 输出
Item    Unit    Purchase
        Price   Date
  • \:用于表示 "自身
    • " 标记字符串的开始和结束
    • 不能单独放一个 \
  • %%显示%
printf("\"hello\"\n");
printf("\\");
"hello"
\

scanf函数

  • 可以包括普通字符和转换说明

  • 检查转换说明数量和输入变量的数量相匹配,以及是否对应

  • 符号&

工作方法

寻找数的起始位置,会忽略空白字符(空格符,水平和垂直制表符,换页符和换行符)

读取规则

  • 读入整数时,先找正负号,再读数字,直到读到第一个非数字时停止
  • 读入浮点数时,寻找正负号(可选),随后一串数字(可能有小数点),指数(可选)。转换说明%e %f %g可以互换
  • 读到不可能属于当前项的字符时,会把此字符放回原处——如末尾的换行符,下一个输入项再读

参见P33详细解释

float类型输入 .3,会存入0.300000

输入3,存入3.000000

scanf("%d%d%f%f", &i, &j, &x, &y);
// 输入为1-20.3-4.0e3\r
// 

普通字符

  • 空白字符。格式串一个空白字符可以匹配输入中任意数量的空白字符,直到遇到非空白字符
  • 其他字符。格式串遇到非空白字符,会将其与输入中的字符比价。相匹配的话,scanf放弃输入字符,继续处理格式串。不匹配,会将其放回原处,异常退出,下一个scanf会读

对于scanf函数,换行等价于空格。

scanf("%d\n", &a);
// 按回车没用,必须输入一个非空白字符
// 因为\n匹配任意多的空白符
scanf("%d\n%d", &a, &b);
// 没事

Q&A

%i 和 %d的区别

  • 在printf格式串中使用没有区别,在scanf格式串中,%i可以匹配八进制(前缀0),十进制,十六进制(前缀0x或0X),如果意外输入零,会有意想不到的结果,推荐%d

要求读入数,却读入了非数值的输入

Enter a number: 23foo

会将23存入变量,foo留到下一个scanf函数调用

Enter a number: foo

没有值被存入变量,foo留到下一个scanf函数调用

如何处理该情况呢

scanf("%*[^\n]");

读取换行符前的所有字符,但是不会存储(*表示赋值屏蔽)。唯一问题是不会读换行符,所以可能需要丢弃换行符

疑问

printf("Enter two fractions: ");
scanf("%d / %d %d / %d", &a, &b, &c, &d);
// 为什么:没有空格,输入是接着:的
上一篇:printf()函数和scanf()函数


下一篇:75、简易四则计算器