标题:C语言库函数scanf()解读
水墨不写bug
(图片来源于网络)
(一)scanf其头文件
我们发现,scanf函数的头文件与printf函数一样,也是stdio.h(这是Standard Input And Output的缩写)(标准输入输出库函数)。
于是,我们大致知道了它的基本功能了。
什么是标准输入输出
简单来说,标准输入一般指的就是键盘,标准输出一般指的就是屏幕。
(二)基本用法
i,概括
scanf()函数用于读取程序用户的键盘输入。
当程序运行到这里时,会停下来,等待用户从键盘输入。
当用户输入数据,按下回车键后,scanf()函数会 “处理”(这里我们先简单地理解,以后水墨详细分享) 用户的输入,将其存入声明过的变量。
我们先看一个应用实例,
如图:
e.g.1
#include<stdio.h> int main() { int a = 0; char arr[20] = { 0 }; scanf("%d %s", &a, arr); printf("%d个人走了进来,其中有我的朋友%s\n", a, arr); return 0; }
ii,与printf()相似
到这里其实我们会发现scanf()函数与printf()的语法类似:
1.都用到了占位符。
2.如果printf()函数与scanf()函数都使用n个占位符,他们的参数是n+1个,且第一个参数是格式字符串。
3.它的其他 n 个参数存放用户输入的变量,格式字符串里有多少个占位符,就有多少个变量。
输出结果:
思考:为什么要用占位符
我们知道,C语言的数据都是有类型的,scanf()函数需要提前知道用户输入的数据类型,才能处理数据。
也就是说,占位符是为了告诉编译器如何解读用户的输入,需要提取的数据是什么类型。
变量取地址?
在e.g.1中,变量a前面加上了&(取地址运算符),我们可以想象一下:如果scanf()函数传递的不是值,而是地址!
也就是说:
在e.g.1中,编译器 把变量a的地址 指向 我们输入的值 “3”。
数组名和字符串指针变量是地址(先了解)
数组名和字符串指针变量存储的是字符串的首元素的首地址,本身就是地址,因此不再加&(取地址运算符)。
iii,与printf()不同的处理方式
scanf()在处理数值占位符时,会自动过滤空白字符,包括:空格 , 制表符 ,换行符。
e.g.2
#include<stdio.h> int main() { int a = 0, b = 0; float x = 0.0, y = 0.0; scanf("%d%d%f%f", &a, &b, &x, &y); printf("%d\n%d\n%f\n%f\n", a, b, x, y); return 0; }
结果:
我们发现:
在输入数据没有结束之前,有 空白字符 或 回车 不影响scanf()解读数据。
思考:为什么空白字符不影响scanf()读取
scanf()处理用户输入的原理是:
用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。
每次解读会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到不符合条件的字符为止,而空白字符默认被忽略。
实例:
#include<stdio.h>
int main()
{
float y = 0.0;
int a = 0;
scanf("%d%f", &a, &y);
printf("%d\n%f\n", a, y);
return 0;
}
结果:
首先scanf根据第一个占位符%d找整形——(-526),读取到 ” . “ 时发现 ” . “ 不是整型的内容,于是停止;
然后scanf根据第二个占位符%f找浮点型——(.23e8),读取到 ” # “ 时发现 ” # “ 不是浮点型的内容,于是读取结束。
iv,scanf的返回值
scanf的返回值是一个整数,表示成功读取变量的个数。
如果没有读取任何值,或者匹配失败,则返回 ’ 0 ‘ ;
在成功读取到任何数据之前,发生了读取错误或者读取遇到文件结尾,则返回EOF(-1)。
(三)占位符
scanf函数的占位符与printf函数基本一致:(我们看一些最常见的)
%c:字符
%d:整型
%f:float型
%lf:double型
%Lf:long double型
%s:字符串
%[ ]:在方括号中指定一组匹配的字符(e.g.[abc]),在遇到除abc外的字符,匹配会自动停止。
#include<stdio.h>
int main()
{
char arr[20] = { 0 };
scanf("%[abc]s", arr);
printf("%s\n", arr);
return 0;
}
如图,在遇到除了 ’ abc ‘ 之外 的 ’ f ‘ 时,scanf函数读取自动停止。
i,特殊的%c
在上述所有占位符中,除了%c,都会自动忽略输入开头的空白字符:
%c占位符表示输入的是字符型,而空白字符本身也是字符,所以%c不会忽略空白字符
如果要强制跳过字符前的空白字符,可以写成scanf(“ %c”,&ch)(也就是在%c前面加上一个空格),这就表示跳过0个或多个空白字符。
ii,特别分享的%s
%s占位符的读取规则是:
从当前的第一个非空白字符开始读起,直到遇到空白字符结束读取。
#include<stdio.h> int main() { char arr[20] = { 0 }; scanf("%s", arr); printf("%s\n", arr); return 0; }
当输入字符串之间有一个空白字符,则读取停止。
iii,赋值忽略符号
赋值忽略符号可以使scanf函数在读取数据时更加灵活:
当我们预定了输入格式我们只有按照格式输入,数据才能被scanf函数成功读取:
#include<stdio.h> int main() { int a = 0, b = 0, c = 0; scanf("%d-%d-%d", &a, &b, &c); printf("%d %d %d", a, b, c); return 0; }
如果输入格式错误,那么,
scanf函数读取数据就会失败:
我们可以换一种更灵活的方式:
将占位符中间的 - 换为 ‘ %*c ’
只要把 * 放在任何占位符的百分号后面,该占位符就不会有返回值,scanf函数按照%c对应解析后就将该字符丢弃。
这里水墨就不给出实例了,你也不妨打开编译器尝试一下!
scanf函数的功能是不是让你对它有了新的认识呢?
完~
未经作者同意禁止转载