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);
// 为什么:没有空格,输入是接着:的