C:多个scanf,当我输入一个scanf的值时,它跳过第二个scanf

我有这块代码(功能省略,因为逻辑是作业的一部分):

#include <stdio.h> int main() { char c = 'q'; int size; printf("\nShape (l/s/t):"); scanf("%c",&c); printf("Length:"); scanf("%d",&size); while(c!='q') { switch(c) { case 'l': line(size); break; case 's': square(size); break; case 't': triangle(size); break; } printf("\nShape (l/s/t):"); scanf("%c",&c); printf("\nLength:"); scanf("%d",&size); } return 0; } 

前两个Scanf的工作很好,没有问题,一旦我们进入while循环,我有一个问题,当你应该被提示输入一个新的形状字符,而是跳转到长度的printf ,并等待从那里输入一个char,然后在循环的下一个循环中输入一个十进制数。

预回圈:

Scanf:形状。 很好
Scanf:长度。 没问题

循环1。

Scanf:形状。 跳过这个
Scanf:长度。 问题是,这个scanf映射到char形状。

循环2
Scanf:形状。 跳过这个
Scanf:长度。 问题是,这个scanf现在映射到int的大小。

为什么这样做?

scanf("%c")ENTER键读取换行符。

当你键入我们说15 ,你键入一个1 ,一个5 ,然后按ENTER键。 所以现在输入缓冲区中有三个字符。 scanf("%d")读取15 ,将其解释为数字15 ,但换行符仍在输入缓冲区中。 scanf("%c")将立即读取这个换行符,然后程序将进入下一个scanf("%d") ,并等待您输入一个数字。

通常的建议是用fgets读取整行输入,并在单独的步骤中解释每行的内容。 解决当前问题的一个更简单的方法是在每个scanf("%d")之后添加一个getchar() scanf("%d")

基本的问题是scanf()在缓冲区中的数字之后留下换行符,然后在下一个传递中用%c读取它。 其实,这是为什么我不使用scanf() ; 我使用线阅读器(例如fgets() )和sscanf() 。 这是更容易控制。

您可能可以通过使用" %c"而不是"%c"格式字符串来解救它。 空白会导致scanf() )在读取字符之前跳过空白(包括换行符)。

但是从长远来看放弃scanf()fscanf()并使用fgets()或者等价的加sscanf()会更容易。 除此之外,错误报告在处理整个字符串时要容易得多,而不是在scanf()失败后留下的流水线。

你也应该一直检查你是否从scanf()得到了一个值。 输入失败 – 经常和可怕。 不要让它破坏你的程序,因为你没有检查。

使用该功能

 void fflushstdin( void ) { int c; while( (c = fgetc( stdin )) != EOF && c != '\n' ); } 

清除你的输入缓冲区。

尝试在scanf中添加一个空格。

 scanf(" %d", &var); // ^ // there 

这将导致scanf()在匹配整数之前丢弃所有的空格。

当您键入形状并回车时,形状被第一个scanf消耗,但ENTER不是! 第二个scanf需要一个数字,因为被认为是一个空格,所以ENTER被跳过,而scanf等待一个有效的输入(一个数字),这个输入又被ENTER终止。 那么,这个数字是消耗的,但是输入不是,所以第一个scanf里面使用它,你的形状提示被跳过…这个过程重复。 您必须在scanfs中添加另一个%c来处理ENTER键。 我希望这有帮助!

在第一次调用scanf之后, '\n'字符仍然保留在输入流中,所以第二次调用scanf()将其读入。使用getchar()

你也可以使用scanf("%c%*c", &c); 读取两个字符并忽略最后一个字符(在这种情况下为\ n)