声明:此文章仅作为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. netty里集成spring注入mysq连接池(一)
  2. items属性的combo_【内存消耗问题】DataGridViewComboboxColoumn关于Items属性和DataSource属性的性能开销问题...
  3. Day1-python基础
  4. [云炬创业基础笔记]第二章创业者测试6
  5. xsmax进入dfu模式_iPhone XS/XS Max如何强制重启?如何进入恢复模式或DFU模式?
  6. 根据年月日判断第多少天,星期几
  7. 参加第三届信息化创新克拉玛依国际学术论坛
  8. URL传Base64 造成报错 Illegal base64 character 20
  9. python表单防重复提交_关于PHP使用token防止表单重复提交的方法
  10. 有多少漏洞都会重来:从ElasticSearch到MongoDB和Redis
  11. 索尼PS5国行版本周开售 后期将推全配色DualSense手柄
  12. 可穿戴设备的主流传感器介绍
  13. 全世界到底有多少软件开发人员?
  14. Exchange 迁移 Public Folder 公共文件夹
  15. 本地Navicat连接虚拟机MySQL
  16. git2.28下载 GIT2.28新版本网盘下载
  17. PC端 流光溢彩 Arduino
  18. httpwatch11.1---专业版
  19. 一篇可以终结房价涨跌讨论的文章(…
  20. C语言项目实战:24点游戏计算器(基于结构体、指针、函数、数组、循环等知识点)

热门文章

  1. 正在连接远程服务器是什么意思,上网显示,“错误678,远程服务器~”是什么意思,怎么处理?...
  2. 【Pyhton 爬虫】正则表达式
  3. 三次握手,四次挥手,为什么是三次握手四次挥手
  4. 改变状态栏颜色html5,iOS改变状态栏颜色
  5. 用mysql语句骂人_MySQL中特别实用的几种SQL语句送给大家
  6. tomcat 部署vue前端项目_Tomcat部署vue项目
  7. Flutter App显示Github Readme文档
  8. 投影仪投屏投不上去怎么回事
  9. 如何用AE做出App store中的卡片动态效果
  10. 原理图库设计1-管脚类型设定