2011-08-03 32 views
4

我有一个程序,但是当程序要求输入时我输入浮点数时,程序突然跳过一个步并移到结束输出。该方案是如下:将浮点数输入到只处理整数的程序

#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的整数版本。

例如:

一个= INT,B =浮

请输入一个数:3
请输入一个数:5.6
3×5 = 15

a =浮动,b =跳过

请输入一个数字3.9
请输入号码:3×-858993460 = 0

在代码中所有的缺陷是故意的,但我只是想知道为什么它的行为我上面所解释的方式。我知道这是因为尝试将浮点数输入到有符号整数中,但我不确定究竟是什么导致它跳过第二个scanf("%d", &b)。谁能解释为什么会发生这种情况?

谢谢。

+0

相关讨论:http://stackoverflow.com/questions/4016073/scanf-fails-why – Mahesh

回答

2

看起来好像scanf()正在读取第二种情况下的“3”,而忽略了“9”。

然后当调用第二个scanf()时,输入缓冲区中已经有文本(“.9”)。

我无法确切地知道它是如何处理“.9”的。它可能已经找到了点,只是在未初始化的情况下在那里中止。通过使用调试器来确定发生了什么应该是一件简单的事情。

但是,基本上,并非所有的输入正在通过第一次调用scanf()进行处理,因此这是第二次调用尝试读取的内容。这就是为什么它不会等待您输入第二个电话的任何数据。

+0

我们如何冲洗/清空缓冲区? – 2011-08-03 06:33:59

+3

我可能会使用'gets()'来读取整行。然后你可以随心所欲地做任何事情,而且不会搞乱随后的输入值。 –

+0

@WTP查看我的答案。 – Clifford

2

控制台输入是行缓冲;当您将3.9输入到%d格式说明符中时,只有3被使用,其余数据保持缓存,所以第二个scanf()调用尝试根据其指定符进行转换,发现'.'并中止转换,使b未定义。

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,的“刷新”代码的修改是必需的,因为转换的字符可能已经'\n'

scanf("%c", &c); 
while(c != '\n' && getchar() != '\n') { /* do nothing */ } 
1

如果下一个要读取的字符无法在指定的当前格式下转换格式说明符,scanf停止扫描并存储当前字段,并且它将移动到下一个输入字段 (如果有的话)。

并且该特定字符被视为未读并用作下一个输入字段或任何后续读取操作的第一个字符。

在上面给出的示例中,它正在扫描3,然后无法将.解析为格式说明符"%d"。因此它将3存储在变量a中,并将.9留为未读。当传递到下一个scanf语句的控件时,它会扫描.,但由于它无法解析.来格式化说明符"%d",它将跳过该字段的输入扫描。

现在作为变量b未分配,它包含一些垃圾值。任何带有垃圾值的算术运算都会导致垃圾值。