使用sscanf()忽略字符旁边的整数

使用sscanf()忽略字符旁边的整数,c,C,对于这个简单的问题,我很抱歉,但我正试图找到一种优雅的方法来避免我的程序看到像“14asdf”这样的输入,并像接受14一样接受它 if (sscanf(sInput, "%d", &iAssignmentMarks[0]) != 0) 有没有一种简单的方法可以防止sscanf像那样从损坏的字符串中提取整数?您想从字符串中读取整数。使用strtol而不是sscanf更容易做到这一点strtol将通过endptr间接返回成功读入数字的最后一个字符后的地址。如果且仅当字符串是数字,则endp

对于这个简单的问题,我很抱歉,但我正试图找到一种优雅的方法来避免我的程序看到像“14asdf”这样的输入,并像接受14一样接受它

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

有没有一种简单的方法可以防止sscanf像那样从损坏的字符串中提取整数?

您想从字符串中读取整数。使用
strtol
而不是
sscanf
更容易做到这一点
strtol
将通过
endptr
间接返回成功读入数字的最后一个字符后的地址。如果且仅当字符串是数字,则
endptr
将指向数字字符串的结尾,即
*endptr==\0

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

(初始空白被忽略。有关详细信息,请参见a。

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
  }
}

如果您可以使用C++特定的能力,使用流测试输入字符串的方法更为清晰。 请点击此处:

如果您想知道,是的,这确实来自另一篇堆栈溢出文章。这篇文章回答了这个问题:

< p>这很简单,没有必要的C++,只需做:< /p>
char unusedChar;
if (sscanf(sInput, "%d%c", &iAssignmentMarks[0], &unusedChar) == 1)

您不能直接阻止
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
指令报告到该点为止使用的字符数,并且不算作转换(因此该格式中只有一个转换)。
%n
自C89以来在
sscanf()
中是标准的


对于提取单个整数,您还可以小心地使用
strtol()
(用它检测错误条件异常困难,但它比不报告或检测溢出的
sscanf()
要好)。但是,这种技术可以在一种格式中多次使用,这通常更方便。

您的意思是有没有办法让sscanf只提取这样一个字符串中的数字字符?您可能还想澄清您是希望“53sd2”返回53还是532。对不起,我应该更清楚,我想要“14asdf”被识别为无效输入,如“53sd2”。我只想识别独立的整数(至少以空格分隔)在C++中,没有任何数字字符是很容易的。这可能是“C++”标签应该从这个问题中删除的。@ AdamWathan,你只想在C中工作吗?我给答案加了一些文本,以便解释代码。希望你不要介意@ SerGe AppDistor。可以自由地编辑或删除它。什么?文本?为什么不合作?在编写代码时提示代码!:-)谢谢Aaron问题是关于
sscanf
,而不是
scanf
,因此数据已经在字符串中。请参阅@Serge的答案。这不对:您可以使用
[fs]scanf()
对于这个OK:您只需要尝试读取数字后面的内容,并检查读取的元素数。