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")
读取1
和5
,将其解释为数字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)