引子
- 首先看一段简单的代码
#include <stdio.h> #include <stdlib.h> int main(void) { int i; char c; scanf("%d",&i); printf("i=%d\n",i); scanf("%c",&c); printf("c=%c",c); system("pause"); return 0; }
- 运行结果
1 i=1 c=
- 为什么第二个scanf没有成功阻塞程序,直接执行的程序呢?貌似c被赋值为空字符
scanf输入原理
-
当程序执行scanf函数时,它会从输入缓冲区中读取数据。输入缓冲区是一个临时存储区域,用于存储从输入设备(如键盘)读取的数据。
-
当用户输入数据时,这些数据会被存储在输入缓冲区中,直到程序调用scanf函数读取这些数据为止。
-
scanf函数会先忽略空格、制表符和换行符等空白字符,然后才会读取非空白字符。这意味着,如果在输入非空白字符之前有空白字符存在,scanf函数会先忽略这些空白字符,然后再读取后面的非空白字符。
-
在读取数据时,scanf函数会阻塞程序的执行,直到读取到符合格式要求的数据为止。如果输入数据的格式不符合要求,scanf函数会返回一个错误码,并且不会将数据存储在变量中。
-
-
在本例中,当程序执行第一个scanf函数读取整数时,它会读取用户输入的数字字符1,并将其转换为整数存储在变量i中。但是由于用户输入的数字后面还有一个换行符,这个换行符会留在输入缓冲区中,等待下一次读取。
-
当程序执行第二个scanf函数读取字符时,它会从输入缓冲区中读取数据。由于输入缓冲区中还有一个换行符,因此scanf函数会将换行符读取到变量c中,导致变量c中存储的值为空字符。
解决
- 为了避免这个问题,可以在读取整数后使用一个额外的scanf函数读取换行符,将缓冲区中的换行符清空
int i; char c; scanf("%d",&i); scanf("%c",&c); // 读取换行符 printf("i=%d\n",i); scanf("%c",&c); printf("c=%c",c);
scanf循环读取
-
关于这里while用法的说明
while(fflush(stdin),(ret= scanf("%d",&i))!=EOF)
- 这种写法是使用逗号运算符将两个表达式连起来,形成一个复合表达式。逗号运算符的作用是先计算左边的表达式,然后再计算右边的表达式,并将右边表达式的值作为整个复合表达式的值。
-
在下面的例子中,while循环的条件部分使用了逗号运算符将两个表达式连接起来
- 调用fflush(stdin)函数,清空输入缓冲区中的数据。
- 调用scanf函数,从标准输入设备(如键盘)读取一个整数,并将其存储在变量i中。
- 将scanf函数的返回值与EOF进行比较,如果不相等,则表示读取成功,继续执行循环体;如果相等,则表示到达文件结尾,退出循环。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int ret;
//fflush(stdin)清空标准输入缓冲区
while(fflush(stdin),(ret= scanf("%d",&i))!=EOF)
{
printf("i=%d\n",i);
}
system("pause");
return 0;
}
-
如果想输入多个整数(每次输入都回车),让 scanf函数读取并打印输出,那么需要一个while 循环。
-
代码中为什么要加入fflush(stdin)函数呢?
-
因为fflush函数具有刷新(清空)标准输入缓冲区的作用。文章来源:https://www.toymoban.com/news/detail-743115.html
- 如果输错,输入的为字符型数据,那么scanf函数就无法匹配成功, scanf函数未匹配成功时其返回值为0,即ret的值为0,但这并不等于EOF,因为EOF的返回值为-1
- 当scanf函数无法匹配成功时,程序仍然会进入循环,这时会导致不断地重复打印
-
改进:字符串并打印对应字符串的大写字母文章来源地址https://www.toymoban.com/news/detail-743115.html
#include <stdio.h> #include <stdlib.h> int main(void) { int i; char c; while(scanf("%c",&c)!=EOF) { if(c!='\n') printf("%c",c-32); else printf("\n"); } system("pause"); return 0; }
到了这里,关于c语言scanf浅谈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!