2009-11-05 46 views

回答

2

你可能需要一個代碼片段更是這樣的:

double number; 
do { 
    printf("Enter a double: "); 
    scanf("%*c"); // burn stdin so as not to buffer up responses 
} while (1 != scanf("%lf", &number)); 

但是喬納森指出,一些更好的行由行解析可能會更好。這種方式直接從stdin掃描對用戶來說並不直觀。

+0

好吧whats that scanf(「%* c」);所有關於? – 2009-11-05 17:17:53

+0

它讀取下一個字符 - 可能是一個換行符,可能是其他的東西 - 而沒有實際分配給任何東西。 – 2009-11-05 17:20:39

+0

好的,謝謝..... – 2009-11-05 17:28:24

8

檢查來自scanf()的返回值;它會告訴您有多少轉換成功。

在上下文中,如果轉換失敗,您會得到0;如果成功,你得到1.

錯誤恢復需要考慮。我通常發現使用fgets()讀取一行數據更容易 - 並且永遠不會獲取()! - 然後用sscanf()處理它。如果轉換失敗,很容易丟棄錯誤的數據。

+0

如何檢查scanf的返回值? – 2009-11-05 17:30:54

+2

檢查scanf的返回值,例如,if(scanf(「%lf」,&number)!= 1)/ * error:number是「invalid」* /;'。 – pmg 2009-11-05 18:07:56

3

如果你想確保用戶期待值由字符串傳遞給ATOF(STR)返回的值一致 - 包括指數符號 - 然後將下面的代碼工作。

您可以使用fgets(str,size,stdin)獲得輸入,並且在將字符串傳遞給解析器之前,甚至不必刪除結尾的換行符。

此外,如果存在解析錯誤,函數會將有罪人物的位置報告給作爲附加參數傳遞的指針。

有一個長形式 - 更容易閱讀,簡短的形式 - 更容易打字。

朗形式:


/* 
    Copyright (C) 2010 S. Randall Sawyer 

This code is in the public domain. It is intended to be usefully illustrative. 
It is not intended to be used for any particular application. If this code is 
used in any application - whether open source or proprietary, then please give 
credit to the author. 

*/ 

#include <ctype.h> 

#define FAILURE (0) 
#define SUCCESS (!FAILURE) 

enum { 
    END_EXPRESSION  = 0x00, 
    ALLOW_POINT   = 0x01, 
    ALLOW_NEGATIVE  = 0x02, 
    REQUIRE_DIGIT   = 0x04, 
    ALLOW_EXPONENT  = 0x08, 
    HAVE_EXPONENT   = 0x10, 
    EXPECT_EXPRESSION  = ALLOW_POINT | ALLOW_NEGATIVE | REQUIRE_DIGIT, 
    EXPECT_INTEGER  = ~ALLOW_POINT, 
    EXPECT_POS_EXPRESSION = ~ALLOW_NEGATIVE, 
    EXPECT_POS_INTEGER = EXPECT_INTEGER & EXPECT_POS_EXPRESSION, 
    EXPECT_EXPONENT  = EXPECT_INTEGER^HAVE_EXPONENT, 
    EXPONENT_FLAGS  = REQUIRE_DIGIT | ALLOW_EXPONENT | HAVE_EXPONENT 
} DoubleParseFlag; 

int double_parse_long (const char * str, const char ** err_ptr) 
{ 
    int ret_val, flags; 
    const char * ptr; 

    flags = EXPECT_EXPRESSION; 
    ptr = str; 

    do { 

    if (isdigit (*ptr)) { 
     ret_val = SUCCESS; 
     /* The '+' here is the key: It toggles 'ALLOW_EXPONENT' and 
      'HAVE_EXPONENT' successively */ 
     flags = (flags + (flags & REQUIRE_DIGIT)) & EXPECT_POS_EXPRESSION; 
    } 
    else if ((*ptr & 0x5f) == 'E') { 
     ret_val = ((flags & (EXPONENT_FLAGS)) == ALLOW_EXPONENT); 
     flags = EXPECT_EXPONENT; 
    } 
    else if (*ptr == '.') { 
     ret_val = (flags & ALLOW_POINT); 
     flags = (flags & EXPECT_POS_INTEGER); 
    } 
    else if (*ptr == '-') { 
     ret_val = (flags & ALLOW_NEGATIVE); 
     flags = (flags & EXPECT_POS_EXPRESSION); 
    } 
    else if (iscntrl (*ptr)) { 
     ret_val = !(flags & REQUIRE_DIGIT); 
     flags = END_EXPRESSION; 
    } 
    else { 
     ret_val = FAILURE; 
     flags = END_EXPRESSION; 
    } 

    ptr++; 

    } while (ret_val && flags); 

    if (err_ptr != NULL) 
    *err_ptr = ptr - 1; 

    return ret_val; 
} 

簡稱:


/* 
    Copyright (C) 2010 S. Randall Sawyer 

This code is in the public domain. It is intended to be usefully illustrative. 
It is not intended to be used for any particular application. If this code is 
used in any application - whether open source or proprietary, then please give 
credit to the author. 

*/ 

#include <ctype.h> 

int double_parse_short (const char * str, const char ** err_ptr) 
{ 
    int ret_val, flags; 
    const char * ptr; 

    flags = 0x07; 
    ptr = str; 

    do { 

    ret_val = (iscntrl (*ptr)) ? !(flags & 0x04) : (
       (*ptr == '.') ? flags & 0x01 : (
       (*ptr == '-') ? flags & 0x02 : (
       ((*ptr & 0x5f) == 'E') ? ((flags & 0x1c) == 0x08) : (
       (isdigit (*ptr)) ? 1 : 0)))); 

    flags = (isdigit (*ptr)) ? 
       (flags + (flags & 0x04)) & 0x1d : (
       ((*ptr & 0x5f) == 'E') ? 0x0e : (
       (*ptr == '-') ? flags & 0x1d : (
       (*ptr == '.') ? flags & 0x1c : 0))); 

    ptr++; 

    } while (ret_val && flags); 

    if (err_ptr != NULL) 
    *err_ptr = ptr - 1; 

    return ret_val; 
} 

我希望這有助於!