如何使用scanf验证输入

时间:2009-01-19 01:34:40

标签: c++ c scanf

如何使用scanf验证用户输入。现在我有类似的东西,但不起作用。

注意:我有atoi只是为了验证scanf验证是否有效。

scanf("%[0987654321.-]s",buf);

i = atoi(buf);

if(i)
    index = i;

6 个答案:

答案 0 :(得分:15)

使用scanf()通常是用户输入的一个坏主意,因为失败会将FILE指针留在未知位置。那是因为scanf代表“扫描格式化”,而且未格式化比用户输入更少。

我建议使用fgets()获取一行,然后在字符串上sscanf()进行实际检查和处理。

这也允许您检查所需字符的字符串(通过循环或正则表达式),scanf函数族不适合。

举例来说,将scanf()"%d""%f"一起使用将停在第一个非数字字符处,这样就不会捕获"127hello"等跟踪错误,这将只给你127.而使用它与无限制%s只是乞求缓冲区溢出。

如果你真的必须使用[]格式说明符(在scanf sscanf中),我认为它不应该被s {1}}。

而且,对于使用该建议的强大输入解决方案,请参阅here。将输入行作为字符串后,您可以sscanf到心中。

答案 1 :(得分:5)

您似乎想要验证字符串作为输入。这取决于您是否要验证字符串是否包含double或int。以下检查double(允许前导和尾随空格)。

bool is_double(char const* s) {
    int n;
    double d;
    return sscanf(s, "%lf %n", &d, &n) == 1 && !s[n];
}

sscanf将返回已转换的项目(不含'%n')。 n将设置为已处理输入字符的数量。如果处理了所有输入,则s [n]将返回终止0字符。两个格式说明符之间的空格占可选的尾部空格。

以下检查int,使用相同的技术:

bool is_int(char const* s) {
    int n;
    int i;
    return sscanf(s, "%d %n", &i, &n) == 1 && !s[n];
}

有一个关于here的问题,其中还包括更多C ++的方法,比如使用字符串流和boost中的函数,比如lexical_cast等。它们通常比scanf这样的函数更受欢迎,因为很容易忘记将一些'%'传递给scanf或某个地址。 scanf不会识别,但是会做任意事情,而lexical_cast例如,如果有什么不对的话会抛出异常。

答案 2 :(得分:1)

我的方法是将用户输入读入字符串,然后使用strtol()将其转换为long。 strtol()返回指向它无法处理的输入字符串中第一个字符的指针,因此通过检查此字符,您将知道是否已解析完整字符串,如下所示:

char *string;
char *endptr;
long result;

scanf("%as", string);
errno = 0;
result = strtol(string, &endptr, 10);
if (ERANGE == errno)
    printf("Input number doesn't fit into long\n");
else if (*endptr)
    printf("%s is not a valid long number - it contains invalid char %c\n",
        string, *endptr);
else
    printf("Got %ld\n", result);

在此片段中scanf()被指示使用格式修饰符“a”自动分配string(这是GNU扩展名)。如果您不使用GNU,请手动分配string并以scanf()格式限制最大大小。

这种方法可以更好地处理错误。

答案 3 :(得分:0)

您在scanf的第一个参数中指定的是转换说明符scanf会尝试将输入转换为格式,但有时您可能会对它匹配的内容感到惊讶:)

您应该首先检查scanf的返回值(它将为您提供匹配输入的数量)。如果你没有得到你期望的数字,那么你就知道输入有问题了。在你的情况下它应该是1.

if( scanf("%[0987654321.-]s", buf) == 1 )
{
      if( sanit_check( buf ) ) 
      {
      /* good input */
      }
      else
      {
      /* invalid input */
      }
}
else 
{
/* invalid input */
}

除此之外,您需要对scanf要求的转换进行完整性检查。

答案 4 :(得分:-1)

如果您只是想读取一个数字,请使用:

int i;
scanf( "%d", &i );

如果你需要做更复杂的检查,你必须自己做。 Scanf不会为你做这件事。

答案 5 :(得分:-4)

“buf”需要成为指针。看起来你正在经历价值。