2012-01-12 49 views
5

對不起,我簡單的問題,但我試圖找到一種優雅的方式,以避免我的程序看一些像「14asdf」輸入和接受它,就像14忽略整數是使用的sscanf()旁邊的字符

if (sscanf(sInput, "%d", &iAssignmentMarks[0]) != 0) 

有沒有一種簡單的方法來防止sscanf從整理出來的損壞的字符串?

+0

你的意思是有沒有辦法讓sscanf只能拿起這樣的字符串中的數字字符?您可能還想澄清您是否希望「53sd2」返回53或532. – Ian 2012-01-12 21:13:08

+0

對不起,我應該更清楚一點,我希望「14asdf」被識別爲無效輸入,就像「53sd2」一樣。我只想識別獨立的整數(至少是空格分隔),而不是非數字字符。 – ARW 2012-01-12 21:23:18

+0

在C++中這很容易。也許應該從這個問題中刪除'C++'標籤? @AdamWathan,你只需要在C中工作的答案? – 2012-01-13 00:44:04

回答

3

您不能直接停止sscanf()做它設計和指定做的事情。但是,你可以使用的sscanf()一個名不見經傳的和很少使用的功能,可以很容易地發現,有一個問題:

int i; 

if (sscanf(sInput, "%d%n", &iAssignmentMarks[0], &i) != 1) 
    ...failed to recognize an integer... 
else if (!isspace(sInput[i]) && sInput[i] != '\0') 
    ...character after integer was not a space character (including newline) or EOS... 

%n上的字符數指令報告消耗到這一點, ,並不算作轉換(因此只有一種格式的轉換)。自C89以來,%nsscanf()中的標準配置。您可以使用strtol() - 仔細地(使用它檢測錯誤條件非常困難,但它優於不會報告或檢測溢出的sscanf())。對於提取單個整數,您也可以使用strtol()。但是,這種技術可以以單一格式多次使用,這通常更方便。

2

你想從字符串中讀取整數。用strtol而不是sscanf這樣做更容易。 strtol將通過endptr間接返回最後一個成功讀入數字的字符後面的地址。如果且只有,該字符串是一個數字,則endptr將指向您的數字字符串的末尾,即*endptr == \0

char *endptr = NULL; 
long n = strtol(sInput, &endptr, 10); 
bool isNumber = endptr!=NULL && *endptr==0 && errno==0; 

(初始的空白將被忽略。詳見一個strtol man page

+0

爲了解釋代碼,我在答案中添加了一些文本。我希望你不介意@ Serge-appTranslator。隨意編輯或刪除它。 – 2012-01-13 00:50:21

+1

什麼?文本?爲什麼不在評論代碼的時候呢! :-)謝謝Aaron – 2012-01-13 06:51:20

0

scanf不是那麼聰明。你必須讀取輸入文字和利用strtol將其轉換。其中一個參數strtolchar *將指向未轉換的第一個字符;如果該字符不是空格或0,然後輸入字符串不是有效的整數:

char input[SIZE]; // where SIZE is large enough for the expected values plus 
        // a sign, newline character, and 0 terminator 
... 
if (fgets(input, sizeof input, stdin)) 
{ 
    char *chk; 
    long val = strtol(input, &chk, 10); 
    if (*chk == NULL || !isspace(*chk) && *chk != 0) 
    { 
    // input wasn't an integer string 
    } 
} 
+0

問題是關於'sscanf',而不是'scanf',因此數據已經在一個字符串中。參見@ Serge的回答。 – 2012-01-13 00:51:28

+0

這是不正確的:你可以使用'[fs] scanf()'來做這件事:你只需要嘗試讀取數字後面的內容並檢查讀取的元素的數量。 – 2012-01-13 01:05:03

2

這很簡單。沒有花哨的C++需要!只要這樣做:

char unusedChar; 
if (sscanf(sInput, "%d%c", &iAssignmentMarks[0], &unusedChar) == 1)