2016-05-15 89 views
0

我想寫一個代碼以確保用戶只輸入1位數。如果用戶輸入類似「0 1 3」的內容,我希望我的程序讀取一條我不知道該如何操作的錯誤消息。任何人都有一個想法如何解決這個問題?我現在的代碼只需要第一個數字,如果一個用戶輸入一串數字,其間有一個空格。C中的數據驗證 - 確保輸入的格式正確

請參閱下面的代碼。謝謝:d

//Prompt the user to enter the low radius with data validation 
printf("Enter the low radius [0.0..40.0]: "); 
do 
{ 
    ret = scanf("%lf", &lowRadius); 
    //type validation 
    if (ret != 1) 
    { 
     int ch = 0; 
     while (((ch = getchar()) != EOF) && (ch != '\n')); 
     printf("Wrong input. Please enter one numerical value: "); 
    } 
    //range validation  
    else if((lowRadius < 0 || lowRadius > 40)) 
    { 
     printf("Incorrect value. Please enter in range 0-40: "); 
    } 
    else break; 
} while ((ret != 1) || (lowRadius < 0 || lowRadius > 40));//end while lowRadius 
+3

你們已經有了代碼。使用'getchar'從輸入中讀取,直到找到換行符。如果任何非空白字符位於換行符之前,則輸入無效。另外,你不需要'do {} while'循環,因爲你反正使用'break'。一個簡單的'while(1){}'或'for(;;){}'循環可以工作。輸入有效時只需「斷開」循環。 – user3386109

+0

這是因爲scanf在很多層次上都是不安全的。看看[這篇文章](http://stackoverflow.com/questions/30577519/error-c4996-scanf-this-function-or-variable-may-be-unsafe-in-c-programming)關於爲什麼不建議使用它,再加上一個替代品。你也應該考慮使用外部或第三部分庫來安全地解析你的輸入。 – Joel

+2

用戶如何使用一位數字輸入像'39'這樣的值?你的意思是'單一號碼'?分數怎麼樣(39.23423)?正如你已經被告知的那樣,'scanf()'可能不是工具;使用'fgets()'來讀取一行,然後使用'sscanf()'或者'strtod()'來轉換值,仔細處理錯誤條件並檢查數字之後和換行符之前是否有碎片。 –

回答

0

閱讀一整行,並與strtod轉換。

+1

這不是一個好的答案。你至少應該提供'strdod'調用示例。 – Adam

2

如果您將該行讀入一個字符串中,然後對其進行分析,則可避免懸掛在未應用的輸入上的問題。你已經完成了大部分工作,但是這顯示瞭如何陷入太多的輸入。它通過在double之後掃描字符串來獲取更多輸入。來自sscanf的返回值告訴您是否存在,因爲它返回成功掃描的項目數。

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

void err(char *message) 
{ 
    puts(message); 
    exit(1); 
} 

int main(void) 
{ 
    double lowRadius = 0.0; 
    char inp[100]; 
    char more[2]; 
    int conv; 
    if(fgets(inp, sizeof inp, stdin) == NULL) { 
     err("Input unsuccesful"); 
    } 
    conv = sscanf(inp, "%lf %1s", &lowRadius, more); // conv is number of items scanned 
    if(conv != 1) { 
     err("One input value is required"); 
    } 
    if(lowRadius < 0.0 || lowRadius > 40.0) { 
     err("Number out of range"); 
    } 
    printf("%f\n", lowRadius); 
    return 0; 
} 

我不確定您對一個數字的規定,因爲這樣不會允許您輸入最大值。

0

亞歷山大有正確的做法,但沒有提供太多的細節。這裏是我該怎麼做,使用getline()讀取輸入,然後使用strspn()和strtod()來解析讀取的輸入。如果你不熟悉指針的使用,這將很難理解 - 但是如果你正在學習C,那麼你最終會得到:

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

int main(void) { 
    double lowRadius; 
    char *lineptr = NULL; 
    size_t n; 
    char *startptr; 
    char *endptr; 
    char *ws = " \t\n"; /* possible whitespace characters */ 

    printf("Enter the low radius [0.0..40.0]: "); 

    while(1) { 
    /* free lineptr if set - neeeded if we iterate on error input */ 
    if(lineptr) { 
     free(lineptr); 
     lineptr = NULL; 
    } 

    /* now read a line of input */ 
    while(getline(&lineptr, &n, stdin) == -1) { 
     /* error returned, just retry */ 
     continue; 
    } 

    /* skip over any leading whitespace */ 
    startptr = lineptr + strspn(lineptr,ws); 

    /* Now try to convert double */ 
    lowRadius = strtod(startptr, &endptr); 

    if(endptr==startptr || endptr[strspn(endptr,ws)] != 0) { 
     /* either no characters were processed - e.g., the 
     line was empty, or there was some non-whitespace 
     character found after the number. */ 
     printf("Wrong input. Please enter one numerical value: "); 
    } else if((lowRadius < 0.0) || (lowRadius > 40.0)) { 
     printf("Incorrect value. Please enter in range 0-40: "); 
    } else { 
     if(lineptr) free(lineptr); 
     break; 
    } 
    } 
    printf("value entered was %lf\n", lowRadius); 
}