2016-03-09 159 views
0

我必須這樣做if語句,或者如果設置了一些無效輸入(如「17d」),它會變成無限循環。爲什麼?我認爲有一些緩衝區,但scanf從標準輸入不從流讀取?C scanf在循環中輸入無效

int age; 

    while (age != 0) { 
    printf("How old are you? "); 

    if(scanf("%d", &age) > 0) { 
     printf("You are %d years old!\n", age); 
    } else { 
     break; 
    } 

    } 
+0

這是因爲非數字'd'仍然保留在輸入緩衝區中,並且無論您嘗試讀取多少次'int'都會停留在那裏。我建議用'fgets'讀入一個字符串,然後用'sscanf'提取'int'。 –

+0

@天氣風向標: 由於這個無限循環,我發現它仍然存在,但scanf從標準輸入讀取?它等待來自stdi的輸入。 cppreference提到來自各種來源的**數據。所以如何使用scanf只接受stdin並忽略緩衝區,而不用刷新'sscanf「..? –

+0

您正在讀取一個'int'。掃描停在第一個非數字字符處,它保留在輸入緩衝區中。通常會通過緩衝區讀取「stdin」,我相信可以禁用緩衝區,但這是處理這種情況的一種不正當的方式,設計操作系統的人員出於某種原因做了這樣的工作 –

回答

0

scanf不成功時,它將輸入留在流中。您需要忽略該行的其餘部分,並要求用戶再次提供輸入。您可以添加一個功能,如:

void ignoreRestOfLine(FILE* fp) 
{ 
    int c; 
    while ((c = fgetc(fp)) != EOF && c != '\n'); 
} 

main調用它:

if(scanf("%d", &age) > 0) { 
    printf("You are %d years old!\n", age); 
} else { 
    // Ignore rest of the line and continue with the loop. 
    ignoreRestOfLine(stdin); 
} 

另一種選擇是在一次讀取的數據線,並使用sscanf來提取行數。

char line[100]; // Make it large enough 
while (age != 0) 
{ 
    printf("How old are you? "); 

    if (fgets(line, sizeof(line), stdin) == NULL) 
    { 
     // Problem reading a line of text. 
     // Deal with it. 
     break; 
    } 
    else 
    { 
     if(sscanf(line, "%d", &age) > 0) 
     { 
     printf("You are %d years old!\n", age); 
     } 
    } 

    // Try to read again 
} 
+0

我不明白爲什麼EOF。通常我會'while(char c = getchar()!='\ 0');'清除一個緩衝區,然後你說** //使其足夠大**但在這種情況下,年齡確定,有時我們不知道它能變得多大? –