2014-01-21 59 views
1

我正在製作一個記錄時間,用戶ID和體重的應用程序。我如何檢查傳遞的第一個令牌是否是整數?我以爲我會使用isdigit,但這隻適用於單個字符。如果第一個標記不是整數,我想輸出無效時間。我目前使用檢查傳遞的字符串是否是整數

sscanf(userInput, "%d %s %f", &timestamp, userID, &weight); 

如果第一個記號不是整數(例如具有字母)我仍然得到了可變時間戳,,我不想一個數字。

int main() 
{ 
    char userInput[99]; 
    int timestamp, timestampT = 0; 
    char userID[31]; 
    userID[0] = 0; 
    float weight, weightT, day, rateW; 

    while(fgets(userInput, 99, stdin) != NULL){ 
     sscanf(userInput, "%d %s %f", &timestamp, userID, &weight); 

     if(timestamp == 0){ 
      printf("%s\n", "Invalid time"); 
     } 
     else if(!isalpha(userID[0]) || userID[0]=='_' || userID[0] == 0){ 
      printf("%s\n", "Illegal userID"); 
     } 
     else if(weight < 30.0 || weight > 300.0){ 
      printf("%s\n", "Illegal weight"); 
     } 
     else if(timestampT > 0){ 
      day = timestampT/86400; 
      rateW = (weightT -weight)/(day - timestamp/86400); 
      if(rateW > 10.0 || rateW < -10.0){ 
       printf("%s\n", "Suspiciously large weight change"); 
      } 

     } 
     else{ 
      printf("%d %s %f \n", timestamp, userID, weight); 
      timestampT = timestamp; 
      timestamp = 0; 
      weightT = weight; 
     } 

     userID[0] = 0; 
    } 
} 
+1

使用sscanf的結果構建另一個字符串,然後將原始字符與重建字符串進行比較。如果它們不同,那麼某些東西不能正確轉換。例如'foo = printf('%d%s,%f',the,values,here); if(!strcmp(foo,userinput)){ruh_roh(); }' –

+1

首先使用['sscanf()'](http://en.cppreference.com/w/c/io/fscanf)的結果確定成功分析了多少個參數。 [注意**第六誡**](http://www.seebs.net/c/10com.html) – WhozCraig

+0

您可以使用'isdigit'查找字符串中的所有字符作爲您的時間戳或使用'isalpha' ID。(更好的寫函數。)或者你可以在第一個'sscanf'中以字符串的形式讀取時間,然後在該字符串上運行'sscanf('...,「%d」,...)'。 –

回答

3

簡單的方法:

char dummy; 
sscanf(userInput, "%d%c %s %f", &timestamp, &dummy, userId, &weight); 
if (!isspace(dummy)) 
    // invalid timestamp input, handle as appropriate 

%d轉換符告訴sscanf離開的第一個非數字字符輸入流,這將是由%c轉換說明被拾起英寸如果此字符不是空格,則輸入不是有效的整數字符串。

不太容易,但IMO更強大的方式:

首先,讀您的時間戳文字:

char timestampStr[N+1]; // where N is the number of digits in the time stamp 
... 
sscanf(userInput, "%s %s %f", timestampStr, userID, &weight); 

然後使用strtol庫函數來將文本轉換爲一個整數值:

char *chk; 
int tmp = (int) strtol(timestampStr, &chk, 10); 

轉換後,chk將指向timestampStr中的第一個非數字字符;如果這個人物以外的任何其他空白或0終止,則輸入的字符串是不是有效的整數:

if (*chk == 0 || isspace(*chk)) 
{ 
    timestamp = tmp; 
} 
else 
{ 
    // invalid timestamp input, handle as appropriate 
} 

我喜歡這種方法,因爲它不會指派任何東西timestamp如果輸入無效;這可能會或可能不會影響您的目的。

編輯

由於chux所指出的,您也應該檢查的sscanf返回值(我很少使用交互式輸入*scanf功能,所以我從來沒有想到這一點)。在第一種情況下,如果結果爲< 4,那麼無論時間戳如何,您都會遇到問題,並應丟棄整條線。同樣,在第二種情況下,如果結果爲< 3,那麼您沒有得到所需的輸入,應該丟棄整條線。

在實踐中,我做的是使用fgets讀線,然後將其分解成使用strtok令牌,然後用strtolstrtod必要做任何的數字轉換。

+1

+1但是我也會檢查'sscanf()'的結果。 – chux

相關問題