2010-05-08 126 views
0

該程序要求輸入一個數字。如果用戶輸入除數字以外的其他任何內容,該程序應循環scanf()函數。如何防止用戶輸入錯誤的輸入?

的代碼,

do{ 
    printf("Enter row number\n"); 
    scanf("%d",&row); 
    }while(row>='a' && row<='z'); 

但上面的代碼不起作用。在輸入信件時,我一直收到錯誤信息。我試圖繞過它,整個事情無限循環。

有什麼建議嗎?

另外我怎麼能告訴C Compiler不要打破循環,除非輸入是INTEGER?

+7

防止用戶輸入不正確的輸入它沒有任何用戶的唯一的傻瓜證明的方式! – Oded 2010-05-08 19:02:08

+0

這是C/C++嗎? – IAbstract 2010-05-08 19:02:42

+1

你爲什麼用'%d'讀一個'char'? – kennytm 2010-05-08 19:04:23

回答

3

您忽略了scanf()的回報,它告訴您輸入的信息是否準確無誤(%d)。如果不準確,則必須進行錯誤恢復,這對於scanf()來說並不特別容易。大多數人採用'讀取輸入行然後解析'的方法,錯誤恢復比較簡單。


我明白,返回值在錯誤檢查必不可少,但如何掃描如果數字或字母?我可以說如果(輸入!=(整數))或類似的東西?

這就是爲什麼人們不使用scanf()。如果將數據行放入緩衝區(字符數組)中,則可以隨時檢查數組的內容。如果您使用scanf(),則在scanf()決定發生錯誤之前,您無法獲得可靠的數據處理機會。

<ctype.h>中的函數(通常也可用作宏)允許您對字符進行分類。 <stdlib.h>中的函數提供了從字符串到各種整數的可靠轉換。

那麼,你可以考慮一下做這樣的事情:

char buffer[256]; 

while (fgets(buffer, sizeof(buffer), stdin)) 
{ 
    ...check contents of buffer using isdigit() etc... 
    ...or just plough ahead with... 
    long value; 
    char *end; 
    errno = 0; 
    value = strtol(buffer, &end, 0); 
    if (errno != 0 || (*end != '\0' && !isspace(*end)) 
     ...diagnose problems... 
} 

此代碼是有點出我的聯賽,此刻..有一個簡單的方法?

好吧,我想你可以使用atoi()代替strtol(),從而簡化了錯誤處理(因爲它是不太精確):

char buffer[256]; 

while (fgets(buffer, sizeof(buffer), stdin)) 
{ 
    int value = atoi(buffer); 
    if (value == 0) 
    { 
     puts("zero read - exiting loop"); 
     break; 
    } 
} 

它沒有得到比這更簡單。我不知道你以前的解決方案的哪一部分是你無法接受的。替代方案,在我看來,是多fiddlier,涉及閱讀一次一個字符和保存數字,並拒絕非數字:

char buffer[256]; 
char *dst = buffer; 
int c; 
int value; 

while ((c = getchar()) != EOF) 
{ 
    if (isdigit(c)) 
    { 
     *dst++ = c; /* Ignoring buffer overflow - bad! */ 
    } 
    else if (isspace(c)) 
    { 
     *dst = '\0'; 
     value = atoi(buffer); 
     break; 
    } 
    else 
    { 
     printf("Unexpected character '%c'!\n", c); 
    } 
} 

等等。在代碼中需要解決各種問題 - 比如在錯誤的字符後重置指針,避免緩衝區溢出,以及處理數字符號等等,以及我寧願留下的各種各樣的東西如fgets()strtol()

+0

感謝您的回覆,是的,我知道返回值在錯誤檢查中至關重要,但如果掃描它的數字或字母,我該如何掃描?我可以說如果(輸入!=(整數))或類似的東西? – NLed 2010-05-08 19:14:54

+0

感謝您的解釋,但此代碼目前有點不在我的聯盟中。有沒有更簡單的方法? – NLed 2010-05-08 20:57:36

+0

@Zazu:解釋完整,代碼簡單。你需要重讀它,直到你理解它。例如,在這個答案中的第三個代碼塊是如何做到這一點,但不應該。第二個代碼塊調用自1977年以來已記錄的兩個函數。如果您無法瞭解fgets和atoi以及while循環的結構如何,那麼是的,您已經脫離了聯盟並且應該介紹編程。我們不會在這裏爲您編寫代碼,而且我們也無法讓您閱讀已寫入的內容。 – msw 2010-05-09 02:50:58

0

您需要閱讀字符,然後確定該字符是否爲數字並根據需要進行轉換。當你輸入完字符後,你還需要檢查一些特殊的字符,比如'q'或者什麼來打斷你的循環。

+0

謝謝,但我想知道轉換是如何完成的。 – NLed 2010-05-08 19:14:00