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输入的是否为整型,以及由此造成死循环的解决办法相关推荐

  1. 用Go语言 判断用户输入的年份是不是闰年 (Golang经典编程案例)

    判断一个年份是否是闰年,需要满足下面条件之一: 年份能被4整除,但不能被100整除: 能被400整除 下面用Go语言实现 判断用户输入的年份是不是闰年,代码如下: package mainimport ...

  2. C语言判断中英文输入

    前言 因为一道老师在pta布置的题目,最后一步是要求能够将中文输入并奇偶排序.在网上多方搜集的资料都是Python的解法,或是一些其他的做法.而自己使用C语言就乱码.无奈,只好自己另寻出路.最终,和朋 ...

  3. C语言学习之求一个3X3的整型矩阵对角线元素之和。

    求一个3X3的整型矩阵对角线元素之和. int main(){int i,j,sum1=0,sum2=0; //定义 int a[3][3]; //定义数组 //给数组元素赋值 for(i=0;i&l ...

  4. C语言学习之求一个3×3的整型矩阵对角线元素之和

    求一个3×3的整型矩阵对角线元素之和 一条对角线 #include <stdio.h> void main(){int a[3][3],i,j,s,s2;printf("请输入9 ...

  5. 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 ...

  6. 对于scanf,strcpy等函数报4996错误的粗暴而简单解决办法

    操蛋的微软,非得在这些东西上搞出另一套标准,新手用微软的IDE开发C++时简直蛋疼的要死,并且使用修改后的方法会导致程序移植性降低. 因此让IDE忽略这些错误是最简单但也是粗暴的解决办法. 以下方法均 ...

  7. c语言用scanf输入指针字符串,c语言如何用scanf输入字符串

    在C语言中,可以使用"scanf("格式控制字符串",变量内存地址)"语句输入字符串.scanf()函数的第一个参数是格式字符串,它指定了输入的格式,并按照格式 ...

  8. 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++) ...

  9. 【C语言】scanf()输入浮点型数据

    #include<stdio.h> int main() {double x1, x2, x3, x4;printf("输入2个浮点数x1,x2:\n");scanf_ ...

最新文章

  1. 心得丨机器学习自学指南(覆盖各个阶段的心得体会哦)
  2. HTML5 javascript修改canvas的大小
  3. android如何监听按钮,Android – 两个onClick监听器和一个按钮
  4. 数据分析:度量数据散布的四分位数
  5. github怎么隐藏自己的pr记录_记便签的软件哪个好?怎么及时记录自己的想法
  6. 超越杭州、北京居首、广州晋级第一梯队……国内城市算力大起底!
  7. jmeter利用influxdb和grafana实现数据可视化
  8. .NET Framework3.0答疑
  9. 鸿蒙系统和你,鸿蒙系统面世,但与您所想的不一样
  10. python中sklearn库更新_python库之sklearn
  11. HTML 图片加载问题
  12. centos mysql server_Centos 7 下载安装 mysql server 5.6 (亲测可用)
  13. Linux内核调优之Sysctl研究
  14. excel文件修复工具_OFFICE文件图标空白的修复方法(亲测有效)
  15. 项目实战第一讲:如何优雅地记录操作日志
  16. 数据分析统计知识—假设检验
  17. HDU 2037 (贪心或记忆化搜索)
  18. 小熊的果篮 2021 CSP J2
  19. 问题记录:node.js连接数据库出现两个问题getaddrinfo ENOTFOUND locahost;Client does not support authentication protoco
  20. Linux系统vscode断点单步运行调试C++程序

热门文章

  1. 微信支付服务器端demo,004-移动支付02-微信支付-服务器开发
  2. Kinect C++简单切水果的一点总结
  3. 小葵多功能转换工具下载
  4. 【线性代数】矩阵初等变换与线性方程组公式定理总结
  5. 二进制转化为十进制和二进制转化为二进制
  6. 插件化的原理分析及实现
  7. Netstat 中 Recv-Q和Send-Q状态
  8. 重磅:又一女程序员被判 9 个月:因薪酬等问题离职,rm -f * 删库,瘫痪 6 个小时...
  9. appium连接模拟器
  10. (含源码)利用Python实现KLT跟踪算法