scanf函数:
- 定义:格式输入函数
- 参数:格式控制字符串,变量地址列表
- 作用:读取stdin标准输入缓冲区 中 某数据 送至 某地址
过程:当stdin流为空时,scanf会等待用户输入,
否则scanf每操作一个stdin流中的按键ASCII码,就将它在stdin中清除; 其中符合格式控制符字符串 要求的 字符串中 的 字符 分三类情况 A.合法数据:存入相应地址,eg:十进制数合法于%d B.分隔符:略去 eg:未指定分隔符时,输入的空白符<下文有介绍> C.未指定操作:无操作 eg:格式控制符字符串最后一个字符为分隔符<下文有实例>
返回值:返回成功赋值的数据个数,读到文件末尾出错则返回EOF
与printf的格式控制字符串的区别:scanf没有精度控制
总结:
用scanf函数进行输入,必须指定输入的数据的类型和格式,不仅繁琐复杂,且易错。
C++保留scanf只为了兼容C,以便过去用C语言写的程序可以在C++的环境下运行。
C++的编程人员都愿意使用cin进行输入,很少使用scanf。
EOF
(1)翻译:end of file
(2)意义:“文字流”的结尾
(3)定义:定义在stido.h首部的常量,一般值为-1
#define EOF (-1);
(4)对象:此处的“文字流”,可以是文件,或者 标准输入(stdin)
(5)区别:stdin无法预知长度,必须手动输入一个字符,达到EOF
Eg:输入ctl+Z
scanf函数的常见特殊情况
背景:
键盘缓冲区:缓存按下enter键之前的按键ASCII码,并显示依序按键对应内容
stdin流:按下enter键之后,缓存键盘缓冲区的ASCII码序列,包括enter键,然后清空键盘缓冲区
- scanf标识当前数据结束:分隔符,或者不合要求格式的数据 eg:%d,输入1.23
分隔符:
一.意义:标识着当前数据已读完,且该符号后面还有待读取的数据
二.分类:
A.空白符:
(1)组成:制表符tab,空格space,新行符enter
(2)特点:无需在格式控制字符串中指定,就算指定了具体某空白符,也是按所有空白符算
scanf(“%d %d”,&a,&b);//指定space作为分隔符,但实际输入时,用tab,enter做分割符也可以
(3)特殊:在仅%c的情况下,空白符当成合法字符;即输入空白符时,scanf(“%c”,&c)等同c=getchar();
(4)说明:putchar和getchar均在ctype.h
B.非空白符:一旦在格式控制字符串中指定,就必须使用这种分割符,不能使用空白符做为分隔符
scanf(“%d,%d”,&a,&b);//指定逗号作为分隔符
(若此部分过于生涩,可以直接看下面的实例)
特殊:
(1)格式字符为%s时,空白符照常当作分隔符
解决:
char str[50];
scanf(“%[^/n]”,str);//将空白符当作 非分隔符处理
(2)格式字符为%c,且无非格式字符时,空白符不会当作分隔符
解决:
方案一:
scanf(“ %c”,&ch);//在%c前加空格;将前一次存入stdin的空白符,当成分隔符处理`
方案二:
getchar();//空白符因取出而被清除
方案三:
fflush(stdin);//清除stdin缓存,即清除遗留的空白符 <fflush函数详见文末>
为什么在%c后加空格不行?(以下测试环境为Ubuntu的Linux系统)
问题
1.第一次需要“按键1+空白符+按键2+enter”:
(1)按键后,还差一个空白符才符合“%c ”,等待用户输入空白符(此次测试输入的空白符是enter)
(2)键入空白符,而空白符写在格式控制字符串中,意味着分隔符,即在分隔符的后面还有一位数据,继续等待用户输入
(3)再次按键,就完全符合了格式字符串的要求,此时等待用户按enter键
(4)键入enter,将键盘缓冲区,和enter键一起存入stdin标准输入缓冲区,并清空键盘缓冲区
2.本该判断前输入的字符类型,却成了判断上次输入字符的类型(第一次除外):
<以下图为例>
Ps:规则:两个缓冲区,均是每操作完某数据,就清除该数据;
fflush
- 作用:冲洗流中的信息
- 用处:通常用于磁盘处理文件
- 位置:stdio.h
- 原型:int fflush(FILE *stream)
- 返回值:成功刷新,指定的流没有缓冲区,只读打开,均返回0
写错误丢失,返回EOF - 注意:fflush是C/C++标准的扩展,∴只是部分编译器具有支持此功能
- 用法:
fflush(stdin);//清空标准输入缓冲区
fflush(stdout);//stdout标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
- 用途:连续使用多个printf函数时,在每一个printf后加上fflush(stdout);
- 原因:上一批存入stdout的数据还未输出完,下一批可能就存入stdout而覆盖掉了上一批数据,∴fflush(stdout);强制马上输出