在CU的C/C++版上看到一个关于fgets()与scanf()相关的问题:
- #include <stdio.h>
-
#include <stdlib.h>
-
-
int main()
-
{
-
-
char a[100];
-
int b;
-
while(1)
-
{
-
printf("Please Enter the messgage:");
-
// getchar();
-
fgets(a,100,stdin);
-
printf("Please enter a integer:");
-
scanf("%d",&b);
-
printf("%s",a);
-
printf("%d\n",b);
-
}
-
return 0;
-
}
-
~
- 执行上面这段代码,在第一次循环是会是正常的
-
“Please Enter the message” 和 “Please enter a integer:” 各占一行,等待输入。
-
但是在第二次循环的时候 这两句话就出现在了同一行, fgets(a,100,stdin)这句话失效了?这是为什么呢?fgets不会等待输入吗?那为什么第一次循环可以得到想要的结果?结果如下图:
-
-
-
另外,如果把 getchar(); 的注释去掉,可以解决上述问题,fgets每次都等待输入,但是在第一次循环的时候,第一个字符会被“吃掉”,但是第二次循环就不会被吃掉,这又是为什么???结果如下图
-
-
请高手指点
下面是我利用gdb进行Debug之后的回复:
- 在你第一次循环时,在提示“Please enter a integer:”之后,你输入了123,注意后面还有一个“回车”,而这个“回车”会一直到你第二次循环的fgets()函数所读取到。所以效果上,第二次循环的fgets()函数好像没有执行一样,实际上它执行了,但是读取的是你第一次循环时,最后输入的“回车”。
-
你可以将fgets()函数换成scanf。就没有这个问题。
-
其实通过gdb可以很容易的找到问题。
-
这个例子显示了scanf和fgets两个函数的区别。
其实这个例子显示了scanf和fgets两个函数的区别:
(1) scanf("%d",&b); 是根据参数"%d"来从输入流中读取字符的,面对整数后面的“回车”,它并不会读取,因为它不符合条件"%d"。所以那个“回车”就一直留在了输入缓冲中,直到第二次循环时 fgets(a,100,stdin); 读取到了a中。所以就给人以第二次fgets函数没有执行的假象。
(2)而fgets(a,100,stdin); 函数会从输入流中读取字符直到:遇到“回车”符,或者达到了100个字符为止。
这个例子似乎说明了C在处理输入输出流方面没有C++那么简洁。
如果将fgets换成scanf也有一点小问题:
scanf("%s", a); 它不会读取我们输入的前缀的空格和后缀的空格,这样就会导致如果输入“the message"时,scanf只能读取到"the",网友pmerofc的解决方法是:
- while(1)
-
{
-
printf("Please Enter the messgage:");
-
fgets(a, 100, stdin);
-
printf("Please enter a integer:");
-
-
scanf("%d", &b);
-
while(getchar() != '\n')
-
;
-
-
printf("%s", a);
-
printf("%d\n", b);
-
}
阅读(3582) | 评论(2) | 转发(2) |