Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:多扫描';s、 当我为一次扫描输入一个值时,它将跳过第二次扫描_C_Scanf - Fatal编程技术网

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时,您可以键入a
1
、a
5
,然后按回车键。现在输入缓冲区中有三个字符
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()
或等效的plus
sscanf()
会更容易。除此之外,如果要处理整个字符串,而不是故障后
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