2011-04-06 43 views
0

說我有C:SCANF驗證

[客房數]

[會議室名稱] [ITEM2的NUM]

[ITEM1的NUM] ...

[數[R | | U | d] [房間名]

...

門]

[房間名] [L的

[開始室] [出口室]

[move1]

[MOVE2]

....

說我用scanf函數,

scanf(" %d", &roomCount); 

scanf(" %s %d %d", room_name, &item1No, &item2No); 

etc ...

How wo我確認用戶輸入正確的輸入了嗎?

感謝

+3

什麼意思是正確的輸入? – 2011-04-06 17:07:18

+0

說如果我想%d,我想期待10而不是等於或10 10 10 – Jono 2011-04-06 17:10:04

回答

2
int input ; 
if (scanf("%d", (&input)) == 0) 
{ 
    while (getchar() != '\n'); // Removes the offending characters that causes 
            // scanf to struck at error occured on future 
            // operations. 
    printf(" \n Invalid value.\n") ; 
} 

所以,如果你希望用戶重新輸入提示,將其存放在while,打破它,如果scanf返回值不是。希望這給你一個想法。

3

好,scanf不會返回的項目數成功讀取。您可以在每次閱讀後將該值與您期望的項目數進行比較。

一個很簡單的例子

#include <stdio.h> 

int main() { 
    int v; 
    if (scanf("%d", &v) != 1) { 
     /* we know something went wrong */ 
    }  
} 
+1

是的,但是如果他應該在一行和下一行中有三個數字,但實際上每行有兩個數字,scanf '不會看到區別。 – 2011-04-06 17:18:01

+0

@Gareth我完全同意。如果輸入數據不是微不足道的,那麼您的答案就是您要描述的方式。 – abeln 2011-04-06 17:27:34

4

使用scanf幾乎總是一個壞主意:它不換行和其他空白區分,這使得它很容易不知道你在哪裏,在力所能及的事你正試圖解析。可能更好:使用fgets讀取行,並將每行填入sscanf,檢查返回值以確保獲得了您要查找的內容。或者,使用一個實際的解析器:使用一個解析器生成器(如flex),或者爲您的數據格式使用某種類型的XML並使用XML解析器等。

設計數據格式可能是明智的做法,這樣解析就很難不注意到同步,並且使數據結構對於讀者更加明顯。

+0

+1,但我懷疑flex/XML/XML解析器的一部分在這種特殊情況下有點矯枉過正;) – abeln 2011-04-06 17:29:17

+0

是的,可能。另一方面,如果這個特定案例變得更大更復雜,我不會感到驚訝。它看起來像是一個交互式小說遊戲地圖的簡單規範;所以也許明天提問者會想要給房間添加描述,然後再允許你從一個移動到另一個,然後在房間中移動對象,......然後很快一個合適的解析器會看起來相當吸引力。 – 2011-04-06 17:32:00

0

scanf不是一個很好的交互輸入工具。

更好的閱讀你的整個輸入線使用fgets文本,然後使用strtok掰成令牌和轉換爲使用strtolstrtoul每個值。這會給你更多的控制權,並且你不必擔心錯誤地接受了一些不好的輸入(例如,如果有人輸入「10p」,scanf將成功轉換並分配10並在輸入流中保留p以使其髒污下一次閱讀;你可能想直接拒絕整個輸入)。