2016-11-09 72 views
3

我從來沒有用C編寫過程,現在我必須編寫小代碼。程序非常簡單 - 我想添加兩個整數。 但是,當我試圖檢查給定的輸入是否是一個數字,並且第一個scanf返回0時,第二個返回0也不等待輸入。 代碼:Scanf返回0而無需等待輸入

int main() 
{ 
    int a = 0; 
    int b = 0; 
    printf("Number a:\n"); 
    if (scanf("%d", &a) != 1) 
    { 
     printf("Not a number. a=0!\n"); 
     a = 0; 
    } 
    printf("Number b:\n"); 
    if (scanf("%d", &b) != 1) 
    { 
     printf("Not a number. b=0!\n"); 
     b = 0; 
    } 
    printf("%d\n", a+b); 
    return 0; 
} 
+0

UV用於檢查輸入函數'...!= 1'的返回值。太多的問題源於不做第一步。至少這篇文章做了這個重要的一步。 – chux

回答

1

這是因爲,一旦第一scanf()失敗了,這是匹配失敗可能是因爲和這引起了匹配失敗的輸入,保持輸入緩衝區內,等待明年的呼叫消耗。

因此,爲了scanf()下次調用也儘量消耗居住在立即輸入緩衝器一樣無效輸入,無需等待明確的外部用戶輸入的輸入緩衝區不是空的。

解決方案:scanf()第一輸入失敗後,必須清理輸入緩衝區,爲一個簡單的例子,像while (getchar() != '\n');應該做的工作。

+0

可能還想檢查換行符。 – dbush

+3

你需要一個更復雜的'while'循環,最好包裝在一個函數中。直到EOF在輸入緩衝區爲空時不會停止讀取,它將被阻止。它只會在EOF處結束,這意味着用戶輸入了ctrl-d(Unix shell)或ctrl-Z(Windows終端)或類似的東西。 – hyde

+0

@hyde是的,基本上你是對的,我只是想描述這個想法,就是這樣。 –

0

這是因爲輸入和輸出在C中不同步。程序可以在用戶輸入後輸出一些行,而輸入沒有被讀取。嘗試運行這段代碼:

char token; 

scanf("%c", &token); 
printf("%c\n", token); 
printf("line 1\n"); 

scanf("%c", &token); 
printf("%c\n", token); 
printf("line 2\n"); 

scanf("%c", &token); 
printf("%c\n", token); 
printf("line 3\n"); 

輸入ABC在一行

你可以想象這就像有兩個分開的控制檯,一個用於輸入,另一個用於輸出。


例如要輸入ASDab。在這種情況下,第一個scanf將找不到任何數字,並返回0.但它也不會從輸入中讀取任何內容。因此,第二個scanf也會看到asd

清除輸入,如果a不是一個數字,你應該輸入該行的所有剩餘字符,直到'\n'(看@ Sourav的解決方案)

1

未能轉換爲數字的輸入第一個fscanf()仍在標準輸入的緩衝區中,並導致第二個fscanf()也失敗。嘗試丟棄違規輸入並重新提示用戶:

#include <stdio.h> 

int main(void) { 
    int a = 0; 
    int b = 0; 
    int c; 
    printf("Number a:\n"); 
    while (scanf("%d", &a) != 1) { 
     printf("Not a number, try again:\n"); 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) 
      exit(1); 
    } 
    printf("Number b:\n"); 
    while (scanf("%d", &b) != 1) { 
     printf("Not a number, try again:\n"); 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) 
      exit(1); 
    } 
    printf("%d\n", a + b); 
    return 0; 
} 

因式分解與效用函數的代碼使得它更清晰:

#include <stdio.h> 

int get_number(const char *prompt, int *valp) { 
    printf("%s:\n", prompt); 
    while (scanf("%d", valp) != 1) { 
     printf("Not a number, try again:\n"); 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) 
      return 0; 
    } 
    return 1; 
} 

int main(void) { 
    int a, b; 

    if (!get_number("Number a", &a) || !get_number("Number b", &b)) { 
     return 1; 
    } 
    printf("%d\n", a + b); 
    return 0; 
} 
0

你可以做使用字符串同樣的事情,不與scanf函數的問題。只需將用戶輸入作爲字符串並將其轉換爲整數。然後將字符串轉換回整數來檢查它們是否相同。如果它們相同,則將a和b視爲整數,如果不是,則執行您的操作(您將需要包含string.h)。這裏是工作代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
int a; 
int b; 
char str1[100]; 
char str2[100]; 

printf("Number a:\n"); 
scanf("%s", &str1); //take input as a string 
a = atoi(str1); //convert string to integer 
snprintf(str2, 100, "%d", a); //convert integer back to string 

//if the integer converted to string is not the same as the string converted to integer 
if (strcmp(str1, str2)!= 0) 
{ 
printf("Not a number. a=0!\n"); 
a = 0; 
} 
printf("Number b:\n"); 
scanf("%s", &str1); 
b = atoi(str1); 
snprintf(str2, 100, "%d", b); 

if (strcmp(str1, str2)!= 0) 
{ 
printf("Not a number. b=0!\n"); 
b = 0; 
} 
printf("%d\n", a+b); 

return(0); 
}