很抱歉这个问题有点简单,但我正在尝试找到一种优雅的方法来避免我的程序接受像"14asdf"这样的输入,并将其视为 14。
if (sscanf(sInput, "%d", &iAssignmentMarks[0]) != 0)
有没有一种简单的方法可以防止sscanf
从被破坏的字符串中提取整数?
很抱歉这个问题有点简单,但我正在尝试找到一种优雅的方法来避免我的程序接受像"14asdf"这样的输入,并将其视为 14。
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以来,在sscanf()
中,%n
是标准的。
如果要提取单个整数,也可以使用 strtol()
- 但要小心(用它检测错误条件非常困难,但它比sscanf()
更好,因为它可以在单个格式中多次使用,这通常更方便。)这很简单。不需要花哨的 C++!只需执行以下操作:
char unusedChar;
if (sscanf(sInput, "%d%c", &iAssignmentMarks[0], &unusedChar) == 1)
您希望从字符串中读取整数。使用strtol
比使用sscanf
更容易实现。 strtol
将通过endptr
间接返回最后一个成功读入数字的字符后面的地址。如果且仅当字符串是数字时,endptr
将指向您的数字字符串的结尾,即*endptr == \0
。
char *endptr = NULL;
long n = strtol(sInput, &endptr, 10);
bool isNumber = endptr!=NULL && *endptr==0 && errno==0;
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 的回答。 - Aaron McDaid[fs]scanf()
来做到这一点。好的:你只需要尝试在数字后读取一些内容,并检查读取的元素数量。 - Dietmar Kühl