我有一个程序,但是当程序要求输入时我输入浮点数时,程序会突然跳过一步并移到结束输出上。该计划如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b,c;
int i;
printf("Please enter a number: ");
scanf("%d", &a);
printf("Please enter a number: ");
scanf("%d", &b);
c = 0;
for(i=0; i < b; i++)
{
c = c + a;
}
printf("%d x %d = %d\n", a, b, c);
return 0;
}
当我输入a
的int和b
的浮点数时,如果b
的小数点后面的数字被截断,程序将按预期输出产品。但是,当我为a
输入一个浮点数时,程序不会获取第二个数字b
的值,而是跳过该步骤并输出a x -858993460 = 0
的整数版本。
例如:
a = int,b = float
请输入一个数字:3
请输入一个数字:5.6
3 x 5 = 15
a = float,b =跳过
请输入数字3.9
请输入一个数字:3 x -858993460 = 0
代码中的所有缺陷都是故意的,但我只是想知道为什么它的行为与我上面解释的方式相同。我知道这是因为尝试将浮点数输入到有符号整数中,但我不确定究竟是什么导致它跳过第二个scanf("%d", &b)
。任何人都可以解释为什么会这样吗?
感谢。
答案 0 :(得分:2)
看起来scanf()
在第二种情况下读取“3”,忽略“9”。
然后当调用第二个scanf()
时,输入缓冲区中已存在文本(“。9”)。
我无法准确地说出它与“.9”的作用。它可能已经找到了点并且在那里b中止了b未初始化。通过调试器来确定发生了什么应该是一件简单的事情。
但是,基本上,并非所有输入都是在第一次调用scanf()
时处理的,所以这是第二次调用尝试读取的内容。这就是为什么它不等你为第二次通话输入任何数据。
答案 1 :(得分:2)
控制台输入行缓冲;当您将3.9输入%d
格式说明符时,只消耗3,其余数据保持缓冲,因此第二次scanf()调用尝试根据其说明符转换它,它找到'.'
并中止转换,留下b undefined。
scanf()
将继续“直播”,直到消耗输入数据末尾的'\n'
为止。你可以这样做:
printf("Please enter a number: ");
scanf("%d", &a);
while( getchar() != '\n' ) { /* do nothing */ }
printf("Please enter a number: ");
scanf("%d", &b);
while( getchar() != '\n' ) { /* do nothing */ }
请注意,如果格式说明符为%c
,则需要修改“flush”代码,因为转换后的字符可能已经是'\n'
:
scanf("%c", &c);
while( c != '\n' && getchar() != '\n' ) { /* do nothing */ }
答案 2 :(得分:1)
如果要读取的下一个字符无法按照 Format Specifier 指定的当前格式进行转换,scanf
将停止扫描并存储当前字段,并将其移至下一个输入字段(如果有的话)。
该特定字符被视为未读,并用作下一个输入字段的第一个字符或任何后续读取操作。
在上面给出的示例中,它正在扫描3
,然后无法将.
解析为格式说明符"%d"
。因此,它将3
存储在变量a
中,将.9
保留为未读。控件在传递到下一个scanf
语句时会扫描.
,但由于无法解析.
格式说明符"%d"
,它会跳过该字段的输入扫描
现在因为未分配变量b
,它包含一些垃圾值。任何带有垃圾值的算术运算都会产生垃圾值。