2014-01-24 59 views
0

所以我的程序必須從用戶輸入中讀取2個整數並打印出來。我使用scanf,並且程序將在不良輸入時退出。但是,當輸入爲「3 + 2」或「3-2」時,scanf忽略「+」和「 - 」符號,並將3和2讀作兩個整數輸入。我想要3 + 2和3-2作爲不好的輸入,程序將退出。我該如何解決它?從用戶輸入中讀取2個整數c

int num1, num2; 
if (scanf("%d%d", &num1, &num2) != 2) { 
     //bad input, exit the program 
    } 
    else { 
     //print the two integers 
+0

從技術上講,它是_is_閱讀兩個整數... –

+0

當你給出兩個值分開它們。例如3 2 –

+1

「 - 」符號不被忽略。 (也是「+」) – BLUEPIXY

回答

3

您必須自己驗證字符串。考慮以下幾點:

#include <stdio.h> 
#include <ctype.h> 

#define MAX_STR_LEN (50) 

int main(void) 
{ 
    char str[MAX_STR_LEN] = {0}; 
    int num1, num2; 

    printf("Enter two numbers: "); 
    fgets(str, MAX_STR_LEN, stdin); 

    for(int i = 0; i < MAX_STR_LEN; i++) 
    { 
     if(!isdigit(str[i]) && (!isspace(str[i])) && (str[i] != '\0')) 
     { 
      if((i != 0) && (str[i - 1] != ' ') && ((str[i] != '+') || (str[i] != '-'))) 
      { 
       printf("'%c' is bogus! I'm self destructing!", str[i]); 
       return -1; 
      } 
     } 

     if((str[i] == '\n') || (str[i] == '\0')) 
      break; 
    } 

    sscanf(str, "%d%d", &num1, &num2); 
    printf("You entered %d and %d. Good job. Pat yourself on the back.", num1, num2); 

    return 0; 
} 

的邏輯如下:

  1. 讀取用戶輸入作爲一個通用的字符串。
  2. 針對違規字符或字符序列的搜索字符串。
  3. 如果沒有,則相應地解析字符串。
  4. 坐下和幸災樂禍。
+1

點4得到我upvote。要點1是至關重要的 - 'scanf'只是一個可怕的功能,應該放在口袋裏的石頭深處。您可能想要考慮用戶可以在兩個值之間放置CRLF。我認爲這是合法的,但是你的代碼還沒有抓住它。 – Floris

+2

任何時候'scanf()'需要兩個或更多的數值,你可以有任意數量的換行符(從0開始)。與普通的'scanf()'相比,'fgets()'加上'sscanf()'是另一個優點。與字符串類似('%s')。 IIRC,只有兩個轉換說明符'%[']','%c'和'%n'不會跳過前導空格;其他一切都做了,空白區包含換行符。 –

2

由於需求似乎是在輸入行兩個數字之間至少有一個空格字符,代碼需要是這樣的:

char s[2]; 
if (scanf("%d%1[ \t]%d", &num1, s, &num) != 3) 
    ...format error... 

這(%1[ \t])尋找一個空白或在第一個數字後立即標籤。第二個數字之前可能會有額外的空白。除非需要,否則您不必對s中的值進行任何操作。

chux固定響應於準確comment

+0

'%[\ t]'有困難,因爲它會掃描一個不確定長度的字符串(由空格和製表符組成),並將結果放在'char c'中。 – chux

+0

這是真的,但很容易通過'%1 [\ t]'固定,它將一個字符讀入一個以空字符結尾的字符串中...... –

+0

和'char c [2]'... – chux

0

"%n"使用以檢測分離白色空間掃描。

int num1, num2; 
int n1, n2; 
if (scanf("%d%n %n%d", &num1, &n1, &n2, &num2) != 2) { 
    ; // bad input, exit the program 
} 
if (n1 == n2) { 
    ; // no space between 1st and 2nd number, exit the program 
} 

另一種方法,類似於@Jonathan萊弗勒,只接受至少1空間

if (scanf("%d%*[ ]%d", &num1, &num2) != 2) { 
    ; // bad input, exit the program 
} 

同意與其他許多說:使用fgets()/sscanf()要好得多。