2011-08-03 29 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未分配,它包含一些垃圾值。任何帶有垃圾值的算術運算都會導致垃圾值。