目录
3.1 printf函数
printf(格式串, 表达式 1, 表达式 2, ...);
int main()
{
int height = 8;
printf("Height = %d",height) //printf("Height = 格式串1",表达式1);
return 0;
}
格式串包含普通字符和占位符(以字符%开头)
3.1.1 占位符
基本概念:用于指示printf函数把数值从内部形式(二进制)转换成打印形式(字符)的方法
例如,占位符%d 指示 printf 函数把 int 型值从二进制形式转换成十进制数字组成的字符串:
#include <stdio.h>
int main()
{
int i, j;
float x, y;
i = 10;
j = 20;
x = 43.2892f;
y = 5527.0f;
printf("i = %d, j = %d, x = %f, y = %f\n", i, j, x, y);
return 0;
}
注意事项:
1、C 语言编译器不会检测占位符的数量是否与输出项的数量相匹配,也不会检测占位符指示的转
换方式与输出项的类型是否匹配,这些都需要自行检查
printf("%d %d\n", i); /*** WRONG ***/
printf("%d\n", i, j); /*** WRONG ***/
printf("%f %d\n", i, x); /*** WRONG ***/
2、占位符也可以显示格式化信息,即%m.pX 格式或%-m.pX 格式,m 和 p 都是整型常量,X 是字母,m 和 p 都是可选的。如果省略 p,m 和 p 之间的小数点也要去掉。
%10.2f %10f %.2f
m = 10 10 m省略了但是.不省略
p = 2 p连带小数点一起被省略 2
x = f f f
3、最小栏宽 m 指明了要显示的z少字符数量:
- 如果要显示的数值所需的字符数少于 m,那么值在字段内是右对齐的(在值前面放置额外的空格)(%4d 将以“空格123” 的形式显示数123)
- 如果要显示的数值所需的字符数多于 m,那么栏宽会自动扩展为所需的尺寸(%4d 将以12345的形式显示数 12345,而不会丢失数字)
- 在 m 前放上一个负号会导致左对齐(%-4d 将以“123空格”的形式显示 123)
4、精度 p 依赖于转换指示符 X 的选择,X表明在显示数值前需要对其进行哪种转换,对数值来说
常用的X有以下几个:
- %d:表示十进制形式的整数。p 指明了待显示数字的少个数,默认为1(不足左侧补零)
- %e:表示指数形式的浮点数。p 指明了小数点后应该出现的数字个数 (默认值为 6),如果 p 为 0,则不显示小数点。
- %f:表示“定点十进制”形式的浮点数,没有指数。p 的含义与 e 中的一样。
- %g:表示指数形式或者“定点十进制”形式的浮点数,形式的选择根据数的大小决定。p 指明了可以显示的有效数字(不是小数点后的数字)的数量。与 f 不同,g 的转换将不显示尾随的零。此外,如果要显示的数值没有小数点后的数字,g 就不会显示小数点。
5、编写程序时无法预知数的大小或者数值变化范围很大的情况下,g 对于数的显示是特别有用的。在用于显示大小适中的数时,g 采用“定点十进制” 形式。但是在显示非常大或非常小的数时,g 会转换成指数形式以便减少所需的字符数
3.1.2 转义字符
常见的转义字符有:
- 警报(响铃)符:\a
- 回退符:\b
- 换行符:\n
- 水平制表符:\t
当这些转义字符出现在 printf 函数的格式串中时,它们表示在显示数值时执行的操作。在大 多数环境中 ,输出\a 会产生一声鸣响,输出\b 会使光标从当前位置回退一个位置,输出\n 会使光 标跳 到下一行的起始位置,输出\t 会把光标移动到下一个制表符的位置。
printf("Item\tUnit\tPurchase\n\tPrice\tDate\n");
输出结果:
Item Unit Purchase
Price Date
2、\" 也是转义字符,它表示字符",因为字符 " 标记字符串的开始和结束,所以 \" 不能出现在没
有使用上述转义字符的字符串内
printf("\"Hello!\"");
输出结果:"Hello!"
3、不能在字符串中只放置单独一个字符 \ ,编译器将认为它是一个转义序列的开始,为了单独显
示字符 \ ,需要在字符串中放置两个字符 \
printf("\\");
3.2 scanf函数
基本概念:scanf 函数与printf函数一样也是由格式串控制的
scanf("%d%d%f%f", &i, &j, &x, &y);
1 -20 .3 -4.0e3
!!!如果 scanf 函数调用中忘记在变量前面放置符号&, 将产生不可预知甚至可能是毁灭性的结果 。程序崩溃是常见的结果。最轻微的后果则是从输入读进来的值无法存储到变量中,变量将保留原有的值 (如果没有给变量赋初始值,那么这个原有值可能是没有意义的)忽略符号&是极为常见的错误,一定要小心!一些编译器可以检查 出这种错误,并产生一条类似“format argument is not a pointer”的警告消息。 如果出现该警告消息, 检查一下是否遗漏了符号&。
3.2.1 scanf函数的工作方法(重要)
基本概念:像 printf 函数一样,scanf 函数是由格式串控制的。调用时,scanf 函数从左边开始处
scanf("%d%d%f%f", &i, &j, &x, &y);
用户的三行输入:
1
-20 .3
-4.0e3
scanf 函数会把它们看作一个连续的字符流:
· · 1 ¤ - 2 0 · · · . 3 ¤ · · · - 4 . 0 e 3 ¤ (提交时,会再次输入一个换行符,你总的enter吧)
s s r s r r r s s s r r s s s s r r r r r r
2、scanf 函数“忽略”了最后的换行符,实际上没有读取它。这个换行符将是下一次 scanf 函数调
用读取的第一个字符,该换行符就会被放在输入缓冲区中(十分重要!!)
scanf("%d%d%f%f", &i, &j, &x, &y);
用户输入:1-20.3-4.0e3¤
用户想要的:1、-2、0.3、-4000
实际的结果:1、-20、0.3(读取.3后自动补零)、
- 占位符%d:第一个非空的输入字符是 1;因为整数可以以 1 开始,所以 scanf 函数接着读取下一个字符,即-。scanf 函数识别出字符-不能出现在整数内,因此把 1 存入变量 i 中,而把字符-放回原处。
- 占位符%d:随后,scanf 函数读取字符-、2、0 和.(句点)。因为整数不能包含小数点,所以 scanf 函数把–20 存入变量 j 中,而把字符.放回原处。
- 占位符%f:接下来 scanf 函数读取字符.、3 和-。因为浮点数不能在数字后边有负号,所以 scanf 函数把 0.3 存入变量 x 中,而把字符-放回原处。
- 占位符%f:最后,scanf 函数读取字符-、4、.、0、e、3 和¤(换行符)。因为浮点数不能包含换行符,所以 scanf 函数把–4.0×103存入变量 y 中,而把换行符放回原处。
3.2.2 格式串中的普通字符
- 空白字符:当在格式串中遇到一个或多个连续的空白字符时,scanf 函数从输入中重复读空白字符,直到遇到一个非空白字符为止(同时会把该非空白字符“放回原处”)
- 非空白字符:当在格式串中遇到非空白字符时,scanf 函数将把它与下一个输入字符进行比较。如果两个字符相匹配,那么 scanf 函数会放弃输入字符,并继续处理格式串。如果两个字符不匹配,那么 scanf 函数会把不匹配的字符放回输入中,然后异常退出,而不进一步处理格式串或者从输入中读取字符
scanf("%d/%d");
用户输入:[空格]5/[空格]96
scanf 函数会跳过第一个空格,把%d 与 5 匹配,把/与/匹配,在寻找下一个整数时跳过一个空格,并把%d 与 96 匹配
scanf("%d/%d");
用户输入:[空格]5[空格]/[空格]96
scanf 函数会跳过第一个空格,把%d 与 5 匹配,然后试图把格式串中的/与输入中的空格匹
配。但是二者不匹配,因此 scanf 函数把空格放回原处,把字符·/·96 留给下一次 scanf 函数调用
来读取,故为了使得scanf函数不会进行第二次调用,应使用格式串"%d[空格]/%d",此时%d之间
的空格就可以很好的把整数5和/之间没有用的空格抵消掉,这也是建议scanf函数的每一个占位符
之间都有一个空格的原因
3.2.3 易混淆的printf函数与scanf函数
printf("%d %d\n", &i, &j); /*** WRONG ***/
2、scanf格式串类似于printf格式串
scanf("%d, %d", &i, &j);
scanf("%d\n");
对 scanf 函数来说,格式串中的换行符等价于空格,两者都会导致 scanf 函数提前进入下一个非空白字符。 像这样的格式串可能会导致交互式程序一直“挂起”,直到用户输入一个非空 白字符为止。
~over~