为什么第二个scanf()不会执行?

14

我正在尝试执行这段代码。

#include <stdio.h> 
int main(void)
{       

     printf("Start from here\n");
     int e, f, g, h;

     scanf("%d,%d", &e, &f);
     scanf("%d, %d", &g, &h);

     printf("%d %d %d %d", e, f, g, h);
}
当我输入2,0或匹配第一个scanf()的格式字符串的内容时,第二个scanf()也会执行。 但是,如果我在第一个scanf()中输入像2-0这样的内容,程序将跳过第二个scanf()并直接进入printf()。 例如,下面是程序的示例运行输入和输出。第二行是输入。
Start from here
1-2  
1 0 -2 -856016624u

注意程序如何完全跳过第二个scanf(),直接进入printf()。为什么这里跳过了第二个scanf()


1
1-2 应该是 1,-2 吗?也就是说,在数字之间需要加上一个逗号。因为这是您告诉 scanf 需要输入的格式。 - kaylum
3
你的第二个scanf正在执行。 e得到了1g得到了-2 - Nishant Bhakta
1
为什么您没有检查scanf的返回值?阅读手册页面可能会有帮助。 - Ed Heal
错误。程序并没有“跳过”第二个 scanf —— 程序执行了它,但结果与您的期望不同。请阅读有关 scanf() 的手册,以了解当您提供与格式不兼容的输入时会发生什么,以及如何检测和处理错误。 - CiaPan
这是其中一个检查scanf()返回值(而不是参数值)的时候,可以通知代码在第一次调用scanf()中无法读取两个参数以及第二次调用scanf()失败无法读取两个参数的情况之一。 - user3629249
3个回答

21
scanf的格式字符串也关心其中的非格式说明符。当您写入“1-2”时,第一个scanf将读取“1”,然后寻找逗号。它找不到逗号,所以就跳过了。现在,第二个scanf将看到“-2”,然后寻找逗号。它仍然找不到逗号,所以就跳过了。
最终结果是另外两个变量将不会被设置,因此它们最终会成为执行时内存位置中的任何垃圾值。
您可以通过检查scanf的返回值来避免这种情况。它会告诉您它找到了多少个值。请尝试以下操作:
#include <stdio.h> 
int main(void)
{       

     printf("Start from here\n");
     int e, f, g, h;

     if (scanf("%d,%d", &e, &f) != 2) { /* error handling */ }
     if (scanf("%d, %d", &g, &h) != 2) { /* error handling */ }

     printf("%d %d %d %d", e, f, g, h);
}

5
注意:作为错误处理的一部分,您可能需要丢弃一些用户输入!可以使用 getchar 循环或者例如 scanf("%*[^\n]"); getchar(); 来完成这个操作... - autistic
5
注意:这里的空格在语义上没有意义;两个格式字符串在功能上是等效的,因为 %d 会隐式地丢弃前导空格。 - autistic
好知道,关于格式化字符串的部分已被删除。 - Peter G
1
为什么要使用 while 而不是 if - Ruslan
因为使用了 while 而被踩了。请将其改为 if 语句。除此之外,这是一个很好的答案。 - David Hammen
显示剩余3条评论

2

在两个格式说明符之间删除逗号

scanf("%d %d", &e, &f); // Remove comma in first argument of scanf
scanf("%d %d", &g, &h);  // Remove comma in first argument of scanf
        ^^^
      Remove comma between two numbers

因为scanf只会跳过空格,而逗号不是空格
当你让scanf读取数字数据时,它实际上会先跳过任何空格,然后读取字符,直到它读取的字符无法组成数字为止。
在这种情况下,当它遇到逗号时,就停止了读取。由于它没有读取任何数字,因此它没有数字可以存储,所以它只是保留原始值。

1
在您的代码中,scanf("%d, %d",&e,&f) 是这样的,所以您应该像这样提供输入:1,22,3 等。
如果您想要输入类似于 0-22-4 的内容,则您的 scanf 必须是这样的:scanf("%d-%d",&e,&f)
这样就不会被跳过了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接