声明:此文章仅作为C语言学习历程中的思路整理,用于解决入门阶段较为浅显的问题,如有错误还请指正。

IDE:小熊猫 Dev-C++

现象描述:

代码要求实现用户输入1或2,通过scanf("%d",&a)读取这个值,从而判断分属于1或2的两种情况。输入非1,2的数字都应该返回"Invalid Number!",并且要求重新输入数字。

while(a!=1&&a!=2){printf("Invalid Number!\n");printf("Enter the number:");scanf("%d",&a);}​

该程序在用户输入整数时均可以正常运行,但是一旦用户输入"a","aasa" 时,程序会陷入死循环。死循环和while语句本身没有关系,无论使用while,goto,for,只要是循环体,均会产生此问题。

程序在后续执行中直接跳过应该由用户输入的scanf("%d",&a);

原理分析:

经多方查找资料得,scanf有缓存区,当输入非法字符(要求的类型与输入的类型不符合),scanf会直接跳过,该输入及不会被接受也不会被清除,被存放在scanf的缓存区,当下次调用scanf函数时,会直接从缓存区读取非法字符,造成死循环。

解决思路:

清除滞留在scanf缓存区的数据,使下一次循环时scanf可以正常的读取用户输入。

解决方法:

1.fflush(stdin);

直接使用缓冲区清除函数fflush(stdin); //stdin代表标准输入;

但fflush(stdin)-这个只能保证在VC上可以生效,在其他编译器上不保证可以起作用。

如果在Linux系统中使用gcc编译,该方法不可用。

资料:

在windows VC下fflush(stdin)是可以实现的,但是linux下不可以。 C标准规定fflush()函数是用来刷新输出(stdout)缓存的。对于输入(stdin),它是没有定义的。但是有些编译器也定义了 fflush(stdin )的实现,比如微软的VC。其它编译器是否也定义了 fflush( stdin)的实现应当查找它的手册。GCC编译器没有定义它的实现,所以不能使用 fflush( stdin )来刷新输入缓存。

2.getchar();

浏览过一些文章,单独使用一行getchar();可以避免单个字符造成的错误,但当输入多个字符时,多出的字符仍会造成多余的循环。

3.通过循环使getchar()读取多次非法字符,直到清除。

while(a!=1&&a!=2){printf("Invalid Number!\n");printf("Enter the number:");while (getchar() != '\n');scanf("%d",&a);   }

可以解决多个非法字符输出的问题。

4.实现fflush(stdin);

既然fflush(stdin)为未定义行为,我们可以自己编写代码简单实现此函数。

char b;
do
{
scanf("%c",&b);
}
while(b !='\n');

这里,使用scanf读取了多余的数据。

char c;
while((c=getchar())!='\n'&& c!=EOF);

这里使用getchar()读取多余数据。

往往一个程序中需要多次使用scanf函数,我们将其单独封装,方便多次调用。

此方法也适用于gcc编译器。

void cl(void)
{char b;do{scanf("%c",&b);}while(b !='\n');
}

if(a!=1&&a!=2)
{
printf("Invalid Number!\n");
printf("Enter the Unit of Weight ([1]-lbs, [2]-kg):");
cl();
scanf("%d",&a);
}

注意:几种方法应该代码位置应该写置scanf之前,若放置之后,虽然能清除缓存区,但仍会多循环一次,推测是由回车造成的,没有进行验证。

C语言由scanf(“%d“,)非法输入字符造成的死循环及其解决方案相关推荐

  1. c语言 字符型数据如何输入,scanf()函数如何输入字符型数据?

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 我的程序: #include"stdio.h" main() { long int QQ_num; char pet_name[20] ...

  2. 10月 24 日 c语言 从键盘上连续输入字符,并统计其中大写字母的个数,直到输入“换行”字符时结束。

    #include <stdio.h> main() { char c,sum1=0; while((c=getchar())!='\n') { if(c>='A'&& ...

  3. c语言如何持续输入字符直到指定字符结束_《小白学C》第三章 常用输入输出函数...

    第三章 常用输入/输出函数 与其他高级语言一样, C语言的语句是用来向计算机系统发出操作指令的. 当我们提到输入时,这意味着要向程序填充一些数据.输入可以是以文件的形式或从命令行中进行.C 语言提供了 ...

  4. c++ 字符串合并_C语言输入字符和字符串(所有函数大汇总)

    C语言输入字符和字符串(所有函数大汇总) C语言有多个函数可以从键盘获得用户输入,它们分别是: scanf():和 printf() 类似,scanf() 可以输入多种类型的数据. getchar() ...

  5. C语言输入字符和字符串

    在C语言中,有多个函数可以从键盘获得用户输入: scanf():和 printf() 类似,scanf() 可以输入多种类型的数据. getchar().getche().getch():这三个函数都 ...

  6. c语言如何用循环输入字符串,C语言使用scanf连续输入字符串出现的问题

    #include int main() { char a,b; scanf("%c",&a): scanf("%c",&b); printf(& ...

  7. C语言中(字符串)输入scanf()、gets()、fgets()以及getchar()、getc()函数的联系与区别

    scanf()函数的输入基于获取"单词",如果使用%s格式,字符串以第一个非空白字符开始读入,读到(但不包括)下一个空白字符(可以是空格.制表符或者换行符).使用scanf()把一 ...

  8. c语言程序设计输入c,C语言程序设计(计算输入字符)

    编写一个程序,该程序读取输入,知道遇到#字符,然后报告读取的空格数目.读取换行符数目以及读取其他所有的字符数目,打印读取到的数目 我虽然写了一个代码,可能是我理解错题意了,有很多问题,比如输入一个#号 ...

  9. C语言scanf()函数格式化输入和printf()格式化输出。

    scanf函数格式化输入和printf格式化输出 要实现的功能如下 完整源代码实现如下 要实现的功能如下 scanf函数格式化输入字符串和字符,printf格式化输出字符串和字符. 完整源代码实现如下 ...

最新文章

  1. matlab单元刚度矩阵整合成整刚,求结构总刚矩阵Matlab源代码
  2. 深入react技术栈(2):JSX语法
  3. Elastic Stack简介
  4. 两个链表是否相交 + 赛马(分桶)
  5. Atitit 最近十年来until2018软件开发领域的趋势 艾龙总结 attilax大盘点总结历史与趋势 1. Keyword sec title 2 2. 语言本身: 2 2.1. 工业标准 2
  6. 如何保证缓存与数据库的双写一致性
  7. HDU---3642:Get The Treasury【立方体体积并】
  8. C11新特性(部分)
  9. psd 替换智能图层的的实现-个性化定制网站
  10. 冬瓜哥详解存储OS变迁
  11. Android蓝牙4.0单车锁应用实例开发
  12. 消防信号总线原理_消防报警联动系统中,什么叫回路总线什么叫RS-485总线?
  13. 基于滑窗捕获的伪卫星系统抗远近效应方法研究
  14. 一只大二狗的Android历程--文件输入输出流 SharedPreference
  15. Mac PS CC2018详细软件按照教程
  16. 敏捷开发 宣言 思想 认识误区
  17. 系分 - 操作系统 - 嵌入式
  18. 从普通 Msconfig 启动选择转为选择性启动
  19. 长途汽车信息管理数据库的设计与实现
  20. (2008-10-31)山西五日自助游记

热门文章

  1. 计算机应用基础小课题,计算机应用基础3课题.doc
  2. python 递归 写平方_Python递归函数如何写?正确的Python递归函数用法
  3. bzoj1355【Baltic2009】Radio Transmission
  4. Linux设置ssh免密登录
  5. Java求阶乘和求阶乘之和
  6. 2020下半年新机最新消息_2020年下半年即将发布新手机有哪些?下半年发布的新款手机汇总...
  7. python预测新航线的票价_2020年中国大学MOOC的APP用Python玩转数据章节测验答案
  8. 关于微课开发的一点新的记录
  9. Linux中的mkdir和touch命令
  10. html打照片墙的代码原理,使用html+css实现一个个人照片墙