【C语言】scanf 详细介绍
里面会放置占位符(与printf()的占位符基本一致),告诉编译器如何解读用户的输入,需要提取的是数据是什么类型。占位符会忽略起首的空格,从 - 处开始处理,读取到 -13 停下来,因为后面的 . 不属于整数的有效字符。解读用户输入时,会从上一次解读遗留的第一个字节开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。例子中,如果用户输入2020-12-12,就会正确解读数据,但是如果输入202
在上一节课中我们学习了变量,有了变量我们就需要给变量输入值,就需要用到 scanf 函数 ,如果需要将变量的值输出在屏幕上就用到 printf函数 ,上代码:
1 #include<stdio.h>
2 int main()
3 { int a=0;
4 scanf("%d",&a);
5 printf("%d\n",a);
6 return 0;
7 }
//scanf函数中,占位符后边的参数需要的是地址,&a,就是取出a的地址
注:标准输入一般指键盘,标准输出一般指屏幕。
1. 基本用法
【敲重点】scanf 函数用于读取用户的键盘输入。
程序运行到这个语句时会停下来等待从用户从键盘输入。
用户输入数据、按下回车键,scanf()就会处理用户的输入,将其存入变量。
它的原型定义在头文件 stdio.h 。
scanf 与 printf 语法相似。
1 scanf("%d",&i);
它的第一个参数是一个 格式字符串 ,里面会放置占位符(与printf()的占位符基本一致),告诉编译器如何解读用户的输入,需要提取的是数据是什么类型。
因为C语言的数据都是有类型的,所以 scanf() 必须提前知道用户输入的数据类型,才能处理数据。
它的其余参数就是存放用户输入的变量,格式字符串里面有多少个占位符,就有多少个变量。
在上面的例子中,scanf()的第一个参数 %d ,表示用户输入的应该是一个整数。%d 就是一个占位符,% 是占位符的标志,d 表示整数。第二个参数 &i ,表示将用户从键盘输入的整数存入变量 i 。
【注意】变量前面必须加 & (指针除外),因为 scanf 传递的不是值而是地址,即将变量 i 的地址指向用户输入的值。如果是指针变量就不需加 &。
上代码:
1 scanf ("%d%f%d",&a,&b,&c);
%d%f%d ,表示用户输入的依次是整数、浮点数、整数。
【注意】scanf()处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等。
所以,用户输入的数据之间,有一个或多个空格不影响 scanf()解读数据;用户使用回车键,将输入分成几行,也不影响解读。
scanf()处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。
解读用户输入时,会从上一次解读遗留的第一个字节开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。
1 #include<stdio.h>
2 int main()
3 {
4 int a=0;
5 float b=0;
6 scanf("%d",&a); //输入 “ -13.45e12# 0”
7 printf("%d\n",a);
8 scanf("%f",&b);
9 printf("%f\n",b)
10 return 0;
11 }
上面,scanf()读取用户输入时,%d 占位符会忽略起首的空格,从 - 处开始处理,读取到 -13 停下来,因为后面的 . 不属于整数的有效字符。%d 读取的就是 -13。
第二次调用 scanf()时,就会从上一次停止解读的地方继续往下读取。由于对应的占位符是 %f ,所以从 "." 开始到 ".45e12",这是采用科学计数法的浮点数格式。后面的 # 不属于浮点数的有效字符,所以会停在这里。
由于 scanf()可以连续处理多个占位符,也可以这样写,上代码:
1 #include<stdio.h>
2 int main()
3 {
4 int a=0;
5 float b=0;
6 scanf("%d%f",&a,&b);
7 printf("%d %f",a,b);
8 return 0;
9 }
2. scanf()的返回值
scanf()的返回值是一个整数,表示成功读取的变量个数。
如果没有读取任何项或者匹配失败,则返回0。
如果在成功读取任何数据之前,发生了读取错误或者遇到读取文件结尾,则返回常量EOL(-1)。
EOF - end of file 文件结束标志
1 #include<stdio.h>
2 int main()
3 {
4 int a = 0;
5 int b = 0;
6 float f = 0.0f;
7 int r=scanf("%d %d %f",&a, &b, &f);
8 printf("a=%d b=%d f=%f",a, b, f);
9 printf("r = %d\n", r);
10 return 0;
11 }
如果输入2个数后,按 ctrl+z ,提前结束输入:
在VS环境中按3次 ctrl+z ,才结束了输入,我们可以看到 r=2 ,表示正确读取了2个数值。如果一个数字都不输入,直接按3次 ctrl+z ,输出的 r 是-1,也就是EOF 。
3. 占位符
scanf()常用的占位符如下,与 printf()的占位符基本一致。
- %c :字符。
- %d :整数。
- %f :float 类型浮点数。
- %lf :double 类型浮点数。
- %Lf :long double 类型浮点数。
- %s :字符串。
- %[ ] : 在方括号中指定一组匹配的字符(比如[0~9]),遇到不在集合之中的字符,匹配将会停止。
上面所有占位符中,除了 %c 以外,都会自动忽略起首的空白字符。%c 不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。
如果要强制跳过字符前的空白字符,可以写成 scanf(" %c, &ch"),即 %c 前加上一个空格,表示跳过0个或多个空白字符。
%s ,不简单等同于字符串。规则是:从当前第一个非空白字符开始读起,直到遇到下一个空白字符(空格、换行符、制表符等)为止。
因为 %s 不会包含空白字符,所以无法用来读取多个单词,除非多个 %s 一起使用。这也就意味着,scanf()不适合读取可能包含空格的字符串,比如歌名或书本名。另外,scanf()遇到 %s 占位符,会在字符串变量末尾存储一个空字符 \0 。
scanf()将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,存储字符串时,很可能会超过数组的边界,导致预想不到的结果。所以,使用 %s 占位符时,应该指定读入字符串的最长长度,即写成 %[m]s ,其中的 [m] 是一个整数,表示读取字符串的最大长度,后面的字符将被丢弃。
1 #include<stdio.h>
2 int main()
3 {
4 char name[11];
5 scanf("%10s",name);
6
7 return 0;
8 }
上面的例子中,name 是一个长为11的字符数组,scanf()的占位符%10s 表示最多读取用户输入的10个字符,后面的字符将被丢齐,这样就不会有 数组溢出 的风险了。
4. 赋值忽略符
有时,用户的输入可能不符合预定的格式。
1 #include<stdio.h>
2 int main()
3 {
4 int year = 0;
5 int month = 0;
6 int day = 0;
7 scanf("%d-%d-%d",&year, &month, &day);
8 printf("%d %d %d\n",year, month, day);
9 return 0;
10 }
例子中,如果用户输入2020-12-12,就会正确解读数据,但是如果输入2020/12/12,scanf()就会解析数据失败。
避免这种情况发生,scanf()提供了一个赋值忽略符 * ,只要把 * 加在任何占位符的% 后面,该占位符就不会返回值,解析后将被丢齐。
1 #include<stdio.h>
2 int main()
3 {
4 int year = 0;
5 int month = 0;
6 int day = 0;
7 scanf("%d%*c%d*c%d",&year, &month, &day);
8 return 0;
9 }
例子中,%*c 就是在占位符的百分号后面,加上了 赋值忽略符 * ,表示这个占位符没有对应的变量,解读后不必返回。
完——
Show time! ———
一首歌送给你
———————————————— Jar of love ——————————————————
唉,别走,对,就是你,点赞收藏加关注哦——
再见——
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)