C语言判断scanf输入的是否为整型,以及由此造成死循环的解决办法
aaaaaa第三篇赶上!
判断scanf输入的是否为整型
# 需求
很多时候我们需要用scanf输入数据,但人为输入的数据可能不符合指定的类型,自然地我们想到了判断输入类型是否正确。
# 实现
那该怎么实现呢?这里我们可以利用scanf的返回值:
scanf返回值:返回成功读入的数据项数
既然这样,那只需要加一个循环,每次检测录入的数据项数是否为全部数据的个数,不是则说明有内容没有录取到(即出现非法字符),此时可以输出提示要求重新输入。
自然地我们写出以下代码:
//以检查输入的是否一个整型为例(VS2019)
int n;
while (scanf_s("%d", &n) == 0)
{printf("输入了非法字符!\n");
}
!!但是,问题出现了
输入非法字符后,结果是这样的:
可以看到,while变成死循环了,并没有给我们再次输入的机会QAQ,到底发生了甚么?!
# 分析
这时候就需要看看scanf的运作原理了
当要求的类型与输入的类型不符合时,scanf会选择直接跳过不接收该输入,注意只是不接收,也就是说缓存区中输入的东西既没被接收也没有被清除,就这么留在那里。
那问题就来了,当下一次用户要输入时,scanf看到缓存区有东西,就直接去读取了,结果又读到与指定类型不符合的,又跳过了,由此触发了无限循环(傻fufu的)
# 解决方案
完成了分析,接下来就好处理了,只需要把缓存区的东西清掉不要让scanf傻傻的又去读取就好啦!
相关代码段:while (getchar() != '\n');
这一句可以简单地解决清楚缓存区的功能
原理是每次都向缓存区读取数据,如果没到尾就继续读取,直到把所有东西读完,再跳出(注意while执行的是空语句)
到这里,问题就都解决了 – 需求 OK,bug KO
# 完整代码
//以检查输入的是否一个整型为例(VS2019)
int n;
while (scanf_s("%d", &n) == 0)
{printf("输入了非法字符,请重新输入:");while (getchar() != '\n');
}
*注:这里的getchar已经不用自己输入了,原因和scanf的死循环一样,缓冲区已经有东西了,getchar会直接读取而不会让我们输入
运行结果:
可以看到问题已经完美解决了~
2021-3-29 方案完善
在后续的使用中,出现了一些问题,如下:
可以看到:
当输入的数据以数字开头,而带有字符时
该解决方案会截取到数字部分,视为合法数据,而后面的字符则留在了缓冲区
这将直接导致下一次的输入被跳过直接取出缓冲区的字符,显然不是我们希望的,所以做了如下改进:
int n;
while (scanf_s("%d", &n) == 0 || getchar() != '\n')
{printf("输入了非法字符,请重新输入:");while (getchar() != '\n'); // 清除缓存区
}
解释:
- 如果为 0 则说明第一个位置出现了字符
- 不为 0 说明前面是整型,此时再取出后面一个字符
- 如果为 \n 则数据没问题,要是还有东西则又是非法字符
这样就可以保证输入的全部为所需的整型
效果如下:
好的,完结收工~
如果还有后续问题欢迎指正!
第3篇完成,打卡!!
冰冻三尺非一日之寒(寒冰小澈)
C语言判断scanf输入的是否为整型,以及由此造成死循环的解决办法相关推荐
- 用Go语言 判断用户输入的年份是不是闰年 (Golang经典编程案例)
判断一个年份是否是闰年,需要满足下面条件之一: 年份能被4整除,但不能被100整除: 能被400整除 下面用Go语言实现 判断用户输入的年份是不是闰年,代码如下: package mainimport ...
- C语言判断中英文输入
前言 因为一道老师在pta布置的题目,最后一步是要求能够将中文输入并奇偶排序.在网上多方搜集的资料都是Python的解法,或是一些其他的做法.而自己使用C语言就乱码.无奈,只好自己另寻出路.最终,和朋 ...
- C语言学习之求一个3X3的整型矩阵对角线元素之和。
求一个3X3的整型矩阵对角线元素之和. int main(){int i,j,sum1=0,sum2=0; //定义 int a[3][3]; //定义数组 //给数组元素赋值 for(i=0;i&l ...
- C语言学习之求一个3×3的整型矩阵对角线元素之和
求一个3×3的整型矩阵对角线元素之和 一条对角线 #include <stdio.h> void main(){int a[3][3],i,j,s,s2;printf("请输入9 ...
- C语言学习之通过指针变量输出整型数组a的10个元素
通过指针变量输出整型数组a的10个元素 int main(){int a[10],i,*p=a;//p的初值是a,p指向a[0] for(i=0;i<10;i++){scanf("%d ...
- 对于scanf,strcpy等函数报4996错误的粗暴而简单解决办法
操蛋的微软,非得在这些东西上搞出另一套标准,新手用微软的IDE开发C++时简直蛋疼的要死,并且使用修改后的方法会导致程序移植性降低. 因此让IDE忽略这些错误是最简单但也是粗暴的解决办法. 以下方法均 ...
- c语言用scanf输入指针字符串,c语言如何用scanf输入字符串
在C语言中,可以使用"scanf("格式控制字符串",变量内存地址)"语句输入字符串.scanf()函数的第一个参数是格式字符串,它指定了输入的格式,并按照格式 ...
- c语言中用scanf和循环语句是怎么给数组一一赋值,如何在C语言中用scanf输入数组...
#include main() struct int num; char name[20]; char sex; int age; stu[5]; int i; for(i=0;i<5;i++) ...
- 【C语言】scanf()输入浮点型数据
#include<stdio.h> int main() {double x1, x2, x3, x4;printf("输入2个浮点数x1,x2:\n");scanf_ ...
最新文章
- 心得丨机器学习自学指南(覆盖各个阶段的心得体会哦)
- HTML5 javascript修改canvas的大小
- android如何监听按钮,Android – 两个onClick监听器和一个按钮
- 数据分析:度量数据散布的四分位数
- github怎么隐藏自己的pr记录_记便签的软件哪个好?怎么及时记录自己的想法
- 超越杭州、北京居首、广州晋级第一梯队……国内城市算力大起底!
- jmeter利用influxdb和grafana实现数据可视化
- .NET Framework3.0答疑
- 鸿蒙系统和你,鸿蒙系统面世,但与您所想的不一样
- python中sklearn库更新_python库之sklearn
- HTML 图片加载问题
- centos mysql server_Centos 7 下载安装 mysql server 5.6 (亲测可用)
- Linux内核调优之Sysctl研究
- excel文件修复工具_OFFICE文件图标空白的修复方法(亲测有效)
- 项目实战第一讲:如何优雅地记录操作日志
- 数据分析统计知识—假设检验
- HDU 2037 (贪心或记忆化搜索)
- 小熊的果篮 2021 CSP J2
- 问题记录:node.js连接数据库出现两个问题getaddrinfo ENOTFOUND locahost;Client does not support authentication protoco
- Linux系统vscode断点单步运行调试C++程序