繁体   English   中英

如何使用scanf验证输入

[英]How to validate input using scanf

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

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

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

i = atoi(buf);

if(i)
    index = i;

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

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

这也允许您检查字符串中是否有您想要的字符(通过循环或正则表达式),这是scanf系列函数不适合的。

举例来说,使用带有"%d""%f" scanf()将停在第一个非数字字符处,因此不会捕获像"127hello"这样的尾随错误, "127hello"会给你127个。并且使用它与非约束%s只是乞讨缓冲区溢出。

如果你真的必须使用[]格式说明符(在scanf sscanf ),我认为它的意思不是s

而且,对于使用该建议的强大输入解决方案,请参见此处 一旦你有一个输入行作为字符串,你可以sscanf到你的心脏内容。

您似乎想要验证字符串作为输入。 这取决于您是否要验证字符串是否包含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];
}

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

我的方法是将用户输入读入字符串,然后使用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()格式限制最大大小。

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

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM