对不起,我简单的问题,但我试图找到一种优雅的方式,以避免我的程序看一些像“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