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

时间:2012-01-12 21:09:02

标签: c

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

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

是否有一种简单的方法可以阻止sscanf将整数从那些错误的字符串中拉出来?

5 个答案:

答案 0 :(得分: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以来%n中的sscanf()是标准的。

为了提取单个整数,你也可以谨慎使用strtol()(用它来检测错误条件是非常困难的,但它比不会报告或检测溢出的sscanf()更好)。但是,这种技术可以在一种格式中多次使用,这通常更方便。

答案 1 :(得分: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

答案 2 :(得分:2)

这很容易。不需要花哨的C ++!只是做:

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

答案 3 :(得分: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
  }
}

答案 4 :(得分:0)

如果您可以使用特定于c ++的功能,则可以使用流测试输入字符串。

点击此处: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

如果你想知道,是的,这确实来自另一个堆栈溢出帖子。哪个回答这个问题: Other answer