栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

声明:此文章仅作为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之前,若放置之后,虽然能清除缓存区,但仍会多循环一次,推测是由回车造成的,没有进行验证。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510499.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号