一,基本介绍
当我们需要给变量输入值就可以使用scanf函数,如果需要将变量的值输出在屏幕上的时候就可以用prinntf函数
二,基本用法
scanf()函数用于读取用户的键盘输入。
程序运行到这个语句时,会停下来,等待用户从键盘输入。
用户输入数据结束以后,按回车键,scanf()函数就会处理用户的输入,将其存入变量。
它的原型定义在头文件stdio.h
第一个参数是一个格式字符串,放置占位符,告诉用户输入数据的类型。
第二个参数就是存放用户输入的变量,格式字符串里面有多少个占位符就有多少个变量
上面示例中,格式字符串%d%d%d%f,表示输入的前三个是整数,后一个是浮点数,把这4个数分别放到a,b,b,c,i 中。
scanf()处理数值占位符时,会自动过滤空白字符,包括空格,制表符,换行符。
所以,用户输入的数据之间,有一个或多个空格不影响scanf()解读数据。另外,用户使用回车键,将输入分成几行,也不影响解读。
上面的示例中,用户分成四行输入,得到的结果与一行输入是完全一样的。 每回按下回车以后,scanf()就会开始解读,如果第一行匹配第一个占位符,那么下次按下回车键,就会从第二个占位符开始解读。
scanf()处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。
上⾯⽰例中,
scanf()
读取⽤⼾输⼊时,
%d
占位符会忽略起⾸的空格,从
-
处开始获取数据,读
取到
-13
停下来,因为后⾯的
.
不属于整数的有效字符。这就是说,占位符
%d
会读到
-13
。
第⼆次调⽤
scanf()
时,就会从上⼀次停⽌解读的地⽅,继续往下读取。这⼀次读取的⾸字符
是
.
,由于对应的占位符是
%f
,会读取到
.45e12
,这是采⽤科学计数法的浮点数格式。后⾯的
#
不属于浮点数的有效字符,所以会停在这⾥。
由于
scanf()
可以连续处理多个占位符,所以上⾯的例⼦也可以写成下⾯这样
2.2scanf的返回值
scanf()的返回值是一个整数,表示成功读取变量的个数。
如果没有读取任何项,或者匹配失败,则返回0。如果在成功读取任何数据之前,发生了读取错误或者遇到读取到文件结尾,则返回常量EOF.
如果输入2个数后,按ctrl+z,提前结束输入
我们可以看到r是2,表示正确读取了2个数值。如果直接按ctrl+z,输出的r是-1,也就是EOF,
2.3占位符
scanf()常用的占位符如下,与printf()的占位符基本一致。
%c
:字符。
%d
:整数。
%f
:
float
类型浮点数。
%lf
:
double
类型浮点数。
%Lf
:
long double
类型浮点数。
%s
:字符串。
%[ ]
:在⽅括号中指定⼀组匹配的字符(⽐如
%[0-9]
),遇到不在集合之中的字符,匹配将会
停⽌。
上面所有占位符之中,除了%c以外,都会自动忽略起首的空白字符,%c不忽略空白字符,总是返回当前的第一个字符,
如果要强制跳过字符前的空⽩字符,可以写成
scanf(" %c", &ch)
,即
%c
前加上⼀个空格,表
⽰跳过零个或多个空⽩字符。
下⾯要特别说⼀下占位符
%s
,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个⾮空
字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。
因为
%s
不会包含空⽩字符,所以⽆法⽤来读取多个单词,除⾮多个
%s
⼀起使⽤。这也意味着,
scanf()
不适合读取可能包含空格的字符串,⽐如书名或歌曲名。另外,
scanf()
遇到
%s
占位
符,会在字符串变量末尾存储⼀个空字符
\0
。
scanf()
将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度。所以,储存字符串时,
很可能会超过数组的边界,导致预想不到的结果。为了防⽌这种情况,使⽤
%s
占位符时,应该指定读⼊字符串的最⻓⻓度,即写成 %[m]s
,其中的
[m]
是⼀个整数,表⽰读取字符串的最⼤⻓度,后 ⾯的字符将被丢弃
arr是一个长度为20的字符数组,scanf()最多输入19个字符,这样就不会有数组溢出的风险了
2.4 赋值忽略符
有时,用户的输入可能不符合预定的格式。
上⾯⽰例中,如果⽤⼾输⼊
2020-01-01
,就会正确解读出年、⽉、⽇。问题是⽤⼾可能输⼊其他
格式,⽐如
2020/01/01
,这种情况下,
scanf()
解析数据就会失败。
为了避免这种情况,
scanf()
提供了⼀个赋值忽略符
*
。 只要把 *
加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃。
%c就是在占位符的百分号后面,加入了赋值忽略符*,表⽰这个占位符没有对应的变量,解读后不必返回。