首页 > 解决方案 > 如何将用户输入限制为仅数字?

问题描述

我的程序是求三角形的面积。如何将用户输入限制为仅数字?

float a, b, c, area, s, dec;       /*Declare variables*/
int m;


printf("Input value of side a : ");     /*User input value of side a*/
scanf("%f", &a);
printf("Input value of side b : ");     /*User input value of side b*/
scanf("%f", &b);
printf("Input value of side c : ");     /*User input value of side c*/
scanf("%f", &c);

标签: c

解决方案


要查看是否scanf能够匹配请求的输入,您必须检查的返回值scanf

printf("Input value of side a : ");
if ( scanf("%f", &a) != 1 )
{
    fprintf( stderr, "input error\n" );
    exit( EXIT_FAILURE );
}

但是,此代码将接受形式为 的输入行3.45idfsgjs。在这种情况下,scanf将匹配3.45而不是从输入流中提取该行的其余部分。

如果您想验证整行输入,您可以使用fgetsandstrtof代替,因为strtof它有一个可选参数,它会告诉您匹配了多少个字符。

float a;
char line[100];
char *p;

printf("Input value of side a : ");

//attempt to read a line of input
if ( fgets( line, sizeof line, stdin ) == NULL )
{
    fprintf( stderr, "input error\n" );
    exit( EXIT_FAILURE );
}

//find newline character
p = strchr( line, '\n' );

//verify that newline character was found
//if not, then line was too long
if ( p == NULL )
{
    fprintf( stderr, "line too long for buffer\n" );
    exit( EXIT_FAILURE );
}

//remove newline character
*p = '\0';

//attemtpt to match input as floating-point number
a = strtof( line, &p );

//verify that entire line was matched
if ( *p != '\0' )
{
    fprintf( stderr, "unable to match entire line\n" );
    exit( EXIT_FAILURE );
}

//input was valid, the variable "a" now
//contains a valid number

由于此输入验证代码相当长,并且在您的情况下必须多次调用,因此创建一个单独的函数来调用fgets和执行输入验证可能是合适的。

但是,上面的代码具有不一致的行为,因为它接受前导空白字符(被 丢弃strtof),但拒绝尾随空白字符。

如果您还想拒绝前导空白字符,则必须调用isspace第一个字符,如果该函数返回 true,则拒绝输入。

如果您想改为接受尾随空格字符,则行

//verify that entire line was matched
if ( *p != '\0' )
{
    fprintf( stderr, "unable to match entire line\n" );
    exit( EXIT_FAILURE );
}

应改为:

//verify that at least one character was matched
if ( p == line )
{
    fprintf( stderr, "unable to match number\n" );
    exit( EXIT_FAILURE );
}

//verify that there are either no remaining characters
//or that all remaining characters are whitespace
while ( *p != '\0' )
{
    if ( !isspace( (unsigned char)*p ) )
    {
        fprintf( stderr, "unable to match entire line\n" );
        exit( EXIT_FAILURE );
    }

    p++;
}

进一步阅读:

远离 scanf() 的初学者指南


推荐阅读