C:多扫描';s、 当我为一次扫描输入一个值时,它将跳过第二次扫描
我有这段代码(由于逻辑是家庭作业的一部分,因此省略了函数):C:多扫描';s、 当我为一次扫描输入一个值时,它将跳过第二次扫描,c,scanf,C,Scanf,我有这段代码(由于逻辑是家庭作业的一部分,因此省略了函数): #包括 int main() { 字符c='q'; 整数大小; 打印件(“\n图形(l/s/t):”; scanf(“%c”、&c); printf(“长度:”); scanf(“%d”,大小(&S); 而(c!='q') { 开关(c) { 案例“l”:行(大小);中断; 大小写:正方形(大小);打断; 案例“t”:三角形(大小);打断; } 打印件(“\n图形(l/s/t):”; scanf(“%c”、&c); printf(“\
#包括
int main()
{
字符c='q';
整数大小;
打印件(“\n图形(l/s/t):”;
scanf(“%c”、&c);
printf(“长度:”);
scanf(“%d”,大小(&S);
而(c!='q')
{
开关(c)
{
案例“l”:行(大小);中断;
大小写:正方形(大小);打断;
案例“t”:三角形(大小);打断;
}
打印件(“\n图形(l/s/t):”;
scanf(“%c”、&c);
printf(“\n长度:”);
scanf(“%d”,大小(&S);
}
返回0;
}
前两个Scanf的工作很好,没有问题一旦我们进入while循环,我有一个问题,当提示您输入一个新的shape char时,它会跳到长度printf
,然后等待从那里获取一个char的输入,然后在循环的下一次迭代中获取一个十进制
预循环迭代:
形状。非常有效扫描:长度。没问题 循环1 形状。跳过这个
扫描:长度。问题是,此scanf映射到shape char 循环2
形状。跳过这个
扫描:长度。问题是,这个scanf现在映射到size int 为什么要这样做
scanf(“%c”)
从回车键读取换行符
当您键入(比如说)15时,您可以键入a1
、a5
,然后按回车键。现在输入缓冲区中有三个字符scanf(“%d”)
读取1
和5
,将它们解释为数字15
,但换行符仍在输入缓冲区中。scanf(“%c”)
将立即读取此换行符,然后程序将继续执行下一个scanf(“%d”)
,并等待您输入一个数字
通常的建议是使用
fgets
读取整行输入,并在单独的步骤中解释每行的内容。解决眼前问题的一个更简单的方法是在每次scanf(“%d”)
之后添加一个getchar()
,当您键入形状并输入时,该形状将被第一次scanf使用,但输入不会被使用!第二个scanf需要一个数字,因此会跳过ENTER,因为它被视为空白,并且scanf会等待有效的输入(一个数字),该输入再次被ENTER终止。嗯,数字已被使用,但ENTER未被使用,因此while中的第一个scanf将使用它,并且您的形状提示将被跳过。。。这个过程重复。您必须在scanfs中添加另一个%c来处理ENTER键。我希望这有帮助 对scanf
的第一次调用完成后,'\n'
字符仍保留在输入流中,因此对scanf()
的第二次调用将其读入。使用函数
void seek_to_next_line( void )
{
int c;
while( (c = fgetc( stdin )) != EOF && c != '\n' );
}
清除输入缓冲区。基本问题是
scanf()
在缓冲区中的数字后保留换行符,然后在下一次传递时用%c
读取它。实际上,这很好地说明了我为什么不使用scanf()
;我使用行读取器(fgets()
,例如)和sscanf()
。这更容易控制
对于格式字符串,您可能可以使用“%c”
而不是“%c”
来拯救它。在读取字符之前,空白导致<代码> ScSff()/Cyto>跳过空白(包括换行符)。
但从长远来看,放弃scanf()
和fscanf()
并使用fgets()
或等效的plussscanf()
会更容易。除此之外,如果要处理整个字符串,而不是故障后scanf()
留下的滴滴,那么错误报告就容易多了
您还应该始终检查是否从
scanf()
转换了值。输入失败-常规且可怕。不要因为您没有检查而让它破坏您的程序。尝试在scanf中添加一个空格
scanf(" %d", &var);
// ^
// there
这将导致scanf()
在匹配整数之前丢弃所有空格。您也可以使用
scanf(“%c%*c”和&c)代码>
读取两个字符并忽略最后一个字符(在本例中为“\n”)这是一个很好的函数。为了便于阅读,我将null语句(单个分号)放在单独的一行。我也喜欢这样,但我认为最好不要使用“flush”一词,因为这在标准中有一个既定的定义,与这里的用法相矛盾。也许seek\u to\u next\u line
将是一个更具描述性的名称?进行@Sebivor建议的更改。也将此放在这里,因为我无法添加自己的答案,这是我看到的最佳答案:scanf(%*[^\n]”;getchar()代码>。如果愿意,可以将其包装成函数。这个答案没有好处;两者在技术上都很好,尽管答案更容易维护,在这种情况下这是一把双刃剑;通常我们倾向于编写更易于维护的代码,但是对于简单版本的白痴来说,可能更容易被修改成不正确的代码。。。你知道我在说什么。。。某种程度的优化。为每个作业选择正确的工具,对吗?根据,scanf
通常会在匹配整数之前丢弃所有空格,无论如何,使此格式字符串中的空格毫无意义:“跳过输入空格字符(由isspace函数指定),除非规范包含[、c或n说明符。”这不会解决问题。%d
已跳过前导空格字符。scanf(“%d”);getchar();
组合将在用户意外输入数字后的空格(或其他垃圾)时失败。
scanf(" %d", &var);
// ^
// there