【bug笔记】scanf不停下来接收输入陷入死循环 fflush(stdin)与其他读取缓冲区字符的方法

main()
{

	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);			//获取控制台输出句柄
	int num;
	score *head = NULL, *stu = NULL;
	system("color f0");
	menu();

	scanf("%d", &num);

	while (1)
	{
		switch (num)
		{
		case 1:
			//head = create();
			break;
		case 2:
			//head = load(head);
			break;
		case 3:
			//head = search(head);
			break;
		case 4:
			//head = del(head);
			break;
		case 5:
			//head = add(head,stu);
			break;
		case 6:
			//print(head);
			break;
		case 7:
			//save(head);
			break;
		case 0:
			exit(0);
			break;
		default:
			SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_RED);
			printf("\t\t  请输入0~7之间的数!");
			SetConsoleTextAttribute(handle, BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			getch();
		}
		menu();
		scanf("%d", &num);
	}
}

这里要接收数字并进行判断,如果是0-7之外的数字就重新清屏接收输入,但是在我第一次输入非数字后std就不再接收我的输入了,仿佛陷入了死循环(在这里要继续吐槽下我买的这本C语言项目开发实战入门,各种bug误导人啊),于是debug了一下发现在第一次输入非数字以后,scanf都不再接收我的输入而是自己进行下一步进行判断。

然后查了下《C Primer Plus》才发现自己基础实在太不牢固了:

scanf依据一个%d转换说明读取一个整数时,每次读取一个字符,跳过所有空白字符,直到读取到第一个空白字符才开始读取,因为要读取整数,所以scanf希望发现一个数字字符或者一个符号(+或-),如果找到一个数字或符号,它便保存该字符,并读取下一个字符,直到遇到非数字字符便认为读到了整数的结尾,然后scanf将非数字字符放回输入流,这意味着在下次读取输入时,首先读到的是上次读取丢弃的非数字字符。

寻找解决办法时发现可以在函数结尾那个scanf之前加一个fflush(stdin)就能解决了,fflush(stdin)会清空输入缓冲区的一个系统函数,看到这个函数感觉找到宝了,这么好用的东西怎么才知道,不过再仔细查查发现又没有那么简单。

参考这篇文章:C 清空输入缓冲区,以及fflush(stdin)的使用误区和解决方法

由于fflush 操作输入流是对 C 标准的扩充,现在很多环境下也已经不支持了。

上面那个文章中也有推荐两种方法:

rewind(stdin)和scanf("%*[^\n]%*c")

rewind是不是很保险的做法,那就主要可以用下scanf("%*[^\n]%*c"):

它是用扫描集将缓冲区中的字符全部读取来实现清除缓冲区的动作。

%*〔^\n〕将逐个读取缓冲区中的'\n'字符之前的其它字符,%后面的*表示将读取的这些字符丢弃,遇到'\n'字符时便停止读取操作,此时,缓冲区中尚有一个'\n'字符遗留,所以后面的%*c将读取并丢弃这个遗留的换行符,这里的星号和前面的星号作用相同。由于所有从键盘的输入都是以回车结束的,而回车会产生一个'\n'字符,所以将'\n'连同它之前的字符全部读取并丢弃之后,也就相当于清除了输入缓冲区。

当然这里也可以利用循环读取缓冲区字符的方法。

在每次调用scanf之后调用下面这个函数

void  eatline()
{
     char  ch;
     while ((ch= getchar ())!= '\n' )
     {
         continue ;
      }
  }


猜你喜欢

转载自blog.csdn.net/yong_ss/article/details/79260815