對不起,我簡單的問題,但我試圖找到一種優雅的方式,以避免我的程序看一些像「14asdf」輸入和接受它,就像14忽略整數是使用的sscanf()旁邊的字符
if (sscanf(sInput, "%d", &iAssignmentMarks[0]) != 0)
有沒有一種簡單的方法來防止sscanf
從整理出來的損壞的字符串?
對不起,我簡單的問題,但我試圖找到一種優雅的方式,以避免我的程序看一些像「14asdf」輸入和接受它,就像14忽略整數是使用的sscanf()旁邊的字符
if (sscanf(sInput, "%d", &iAssignmentMarks[0]) != 0)
有沒有一種簡單的方法來防止sscanf
從整理出來的損壞的字符串?
您不能直接停止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以來,%n
是sscanf()
中的標準配置。您可以使用strtol()
- 仔細地(使用它檢測錯誤條件非常困難,但它優於不會報告或檢測溢出的sscanf()
)。對於提取單個整數,您也可以使用strtol()
。但是,這種技術可以以單一格式多次使用,這通常更方便。
你想從字符串中讀取整數。用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。
爲了解釋代碼,我在答案中添加了一些文本。我希望你不介意@ Serge-appTranslator。隨意編輯或刪除它。 – 2012-01-13 00:50:21
什麼?文本?爲什麼不在評論代碼的時候呢! :-)謝謝Aaron – 2012-01-13 06:51:20
scanf
不是那麼聰明。你必須讀取輸入文字和利用strtol
將其轉換。其中一個參數strtol
是char *
將指向未轉換的第一個字符;如果該字符不是空格或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
}
}
問題是關於'sscanf',而不是'scanf',因此數據已經在一個字符串中。參見@ Serge的回答。 – 2012-01-13 00:51:28
這是不正確的:你可以使用'[fs] scanf()'來做這件事:你只需要嘗試讀取數字後面的內容並檢查讀取的元素的數量。 – 2012-01-13 01:05:03
我如果你可以使用C++特有的功能,那麼有更清晰的方法來測試使用流的輸入字符串。
入住這裏: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2
如果你想知道,是的,這確實來自另一個堆棧溢出後。它回答了這個問題: Other answer
這很簡單。沒有花哨的C++需要!只要這樣做:
char unusedChar;
if (sscanf(sInput, "%d%c", &iAssignmentMarks[0], &unusedChar) == 1)
你的意思是有沒有辦法讓sscanf只能拿起這樣的字符串中的數字字符?您可能還想澄清您是否希望「53sd2」返回53或532. – Ian 2012-01-12 21:13:08
對不起,我應該更清楚一點,我希望「14asdf」被識別爲無效輸入,就像「53sd2」一樣。我只想識別獨立的整數(至少是空格分隔),而不是非數字字符。 – ARW 2012-01-12 21:23:18
在C++中這很容易。也許應該從這個問題中刪除'C++'標籤? @AdamWathan,你只需要在C中工作的答案? – 2012-01-13 00:44:04