【问题标题】:Data Validation in C when the user inputs an incorrect value to avoid program crash当用户输入不正确的值以避免程序崩溃时在 C 中进行数据验证
【发布时间】:2014-09-01 06:57:41
【问题描述】:

如何确保用户只输入一个整数值以使程序不会崩溃?

如果用户输入的不是整数,我想: printf("请重新检查您的输入);

printf("How many values do you want to enter? \t");
    int g;
    scanf("%d", &g);

【问题讨论】:

  • 查看scanf的返回值。见en.cppreference.com/w/c/io/fscanf
  • 此外,您可能希望在检测到无效输入后刷新该行的其余部分。必须有一个很好的副本
  • 这里肯定有很多其他问题是重复的。其中一些可能会列在相关问题中,但我觉得这些都不是“规范”答案。
  • 您将需要检查来自scanf() 的返回值,并将代码包装在一个循环中,如果转换失败,可能会安排吞噬输入行的其余部分(因为您可能需要跳过他们输入thirty-three,您希望他们输入33)。您应该区分“转换失败”(0) 和文件结尾 (EOF)。

标签: c int user-input scanf validation


【解决方案1】:

我会说,检查scanf的返回值:

这些函数返回成功匹配和分配的输入项的数量,该数量可能少于提供的数量,在早期匹配失败的情况下甚至为零。

如果在第一次成功转换或发生匹配失败之前到达输入结尾,则返回值 EOF。如果发生读取错误,也会返回 EOF,在这种情况下,会设置流的错误指示符(参见 ferror(3)),并设置 errno 来指示错误。

【讨论】:

    【解决方案2】:

    我想说您必须进行一些自定义验证以检查scanf 是否读取整数。

    我也建议使用fgetsscanf() 中没有边界检查)

    你可以这样做

    #include <stdio.h> 
    #include <ctype.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    int validate ( char *a )
    {
      unsigned x;
      for ( x = 0; x < strlen ( a ); x++ )
        if ( !isdigit ( a[x] ) ) return 1;
      return 0;
    }
    
    int main ( void )
    {
      int i;
      char buffer[BUFSIZ];
      printf ( "Enter a number: " );
      if ( fgets ( buffer, sizeof buffer, stdin ) != NULL ) {
        buffer[strlen ( buffer ) - 1] = '\0';
        if ( validate ( buffer ) == 0 ) {
          i = atoi ( buffer );
          printf ( "%d\n", i );
        }
        else
          printf ( "Error: Input validation\n" );
      }
      else
        printf ( "Error reading input\n" );
      return 0;
    }
    

    【讨论】:

    • 此代码不允许前导或尾随空格,也不允许加号或减号。这是否重要是另一个问题。
    • 根据输入和使用的平台,此代码可能会调用未定义的行为。请注意,函数isdigit 的参数类型为int,而不是char。根据该函数的文档,使用其值不能表示为 unsigned char 且不是值 EOF 的参数调用该函数将调用未定义的行为。因此,对于签名char 的平台(大多数平台),某些输入将调用未定义的行为。您应该将参数转换为unsigned char
    【解决方案3】:

    试试这样的-

    #include<stdio.h>
    int main()
    {
            int num;
            printf("Enter the number\n");
    
            if((scanf("%d",&num)) == 1){ // checking return value of scanf here!
    
                    printf(": %d\n",num);
                    // do your stuff here
            }
            else
                    printf("Please recheck your input!\n");
    
            return 0;
    }
    

    这里如果输入被正确读取并分配scanf将返回1,否则返回0。

    样本输出-

    root@sathish1:~/My Docs/Programs# ./a.out 
    Enter the number
    2
    : 2
    root@sathish1:~/My Docs/Programs# ./a.out 
    Enter the number
    asd
    Please recheck your input!
    

    【讨论】:

    • 但是,像23hahaha 这样的用户输入可能会被接受(并理解为 23)。我不知道这对 OP 是否重要。
    • @BasileStarynkevitch 如果是这种情况,我们需要扫描字符串格式的输入,必须检查每个字节!如果是int,那么我们可以使用atoi进行转换!
    猜你喜欢
    • 2015-12-09
    • 2012-08-07
    • 2019-05-30
    • 1970-01-01
    • 2021-12-28
    • 2021-10-03
    • 2015-02-10
    • 1970-01-01
    • 2015-07-20
    相关资源
    最近更新 更多