首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >接受C中的多个用户输入

接受C中的多个用户输入
EN

Stack Overflow用户
提问于 2021-10-30 18:09:42
回答 1查看 140关注 0票数 0

我正在用C编写一个程序,它接受用户输入的任何一种格式:

  1. 字符串,int
  2. 字符串、int、int或浮点数

有效输入的一些例子:

  1. 苏珊5
  2. 戴维10 24
  3. 莎拉6 7.5

我如何用C来完成这个任务?

下面是我到目前为止掌握的代码:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

int main()
{
    char name[10];
    int num1;
    int num2;

    if(scanf("%s %d", name, &num1) != 2 || scanf("%s %d %d", name, &num1, &num2) != 3)
    {
            printf("Failure");
    }
    else
    {
        printf("Pass");
    }
}

这将打印"Failure“(如果有无效的用户输入)和"Pass”(如果用户输入有效)。这里的问题是,这段代码迫使我输入两种格式,以便打印“Pass”。因此,如果我输入"Susan 5“,我将不得不输入"David 1024”,以便打印"Pass“,即使我有一个或有条件的,而不是一个和条件的,这我不明白。我想要的是一旦我输入"Susan 5“并点击enter,我的程序应该能够打印”Pass“。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-30 19:13:36

如果我正确理解你的问题,有三种可能的输入:

一个单词后面跟着一个整数

  1. 没什么,或者
  2. 另一个整数,或
  3. 浮点数。

由于您已经在注释部分中指出,在第2种情况下,将第二个整数存储为浮点数是可以接受的,所以我们可以将第2和第3种情况视为相同的情况。

排在队伍里

代码语言:javascript
运行
复制
if(scanf("%s %d", name, &num1) != 2 || scanf("%s %d %d", name, &num1, &num2) != 3)

第二个scanf函数调用可能无法工作,因为第一个函数已经消耗了部分输入。因此,您应该首先使用fgets读取一行输入,并将对scanf的调用替换为对sscanf的调用

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char name[10];
    int num1;
    double num2;

    char line[100];
    int num_consumed;

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

    //verify that entire line was read in
    if ( strchr( line, '\n' ) == NULL )
    {
        fprintf( stderr, "line too large for input buffer!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to convert first two parameters
    if ( sscanf( line, "%9s%d%n", name, &num1, &num_consumed ) != 2 )
    {
        printf( "Failure\n" );
        return 0;
    }

    printf( "Pass\n" );

    //attempt to read third parameter as a floating-point number
    if ( sscanf( line+num_consumed, "%lf", &num2 ) != 1 )
    {
        printf( "User entered only one number:\n%d\n", num1 );
    }
    else
    {
        printf( "User entered two numbers:\n%d\n%f\n", num1, num2 );
    }
}

此程序具有以下行为:

输入错误:

代码语言:javascript
运行
复制
Susan David
Failure

只有一个数字作为输入:

代码语言:javascript
运行
复制
Susan 5
Pass
User entered only one number:
5

两个整数作为输入:

代码语言:javascript
运行
复制
David 10 24
Pass
User entered two numbers:
10
24.000000

一个整数和一个浮点数作为输入:

代码语言:javascript
运行
复制
Sarah 6 7.5
Pass
User entered two numbers:
6
7.500000

程序的一个可能问题是它不检查第二个sscanf失败的原因。例如,它将处理输入

Susan 5 dslfhksdhfkl

与用户输入的内容相同:

Susan 5

这个问题并没有说明在这种情况下输入是否应该打印Failure。但是,同时在注释部分中,您已经声明程序应该拒绝输入,例如:

代码语言:javascript
运行
复制
Susan 5 ddggghh
David 10 24 dslfhksdhfkl

因此,在下面的程序中,我在这两种情况下都添加了一个额外的检查,以验证匹配字符之后的所有剩余字符都是空白字符 (至少在行尾总会有一个换行符)。如果没有,则输入将被拒绝。

为了确定一个字符是否是空白字符,我使用函数isspace

在这里,使用这些附加检查更新的程序:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>

//this function will return whether a string consists
//entirely of whitespace characters
bool is_string_whitespace( const char *str )
{
    for ( const char *p = str; *p != '\0'; p++ )
    {
        if ( !isspace( (unsigned char)*p ) )
            return false;
    }

    return true;
}

int main()
{
    char name[10];
    int num1;
    double num2;

    char line[100], *p;
    int num_consumed;

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

    //verify that entire line was read in
    if ( strchr( line, '\n' ) == NULL )
    {
        fprintf( stderr, "line too large for input buffer!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to convert first two parameters
    if ( sscanf( line, "%9s%d%n", name, &num1, &num_consumed ) != 2 )
    {
        printf( "Failure\n" );
        return 0;
    }

    //attempt to read third parameter as a floating-point number
    p = line + num_consumed;
    if ( sscanf( p, "%lf%n", &num2, &num_consumed ) == 1 )
    {
        //verify that all remaining characters are whitespace
        if ( !is_string_whitespace( p+num_consumed ) )
        {
            printf( "Failure" );
            return 0;
        }
        printf( "Pass\n" );
        printf( "User entered two numbers:\n%d\n%f\n", num1, num2 );
    }
    else
    {
        //verify that all remaining characters are whitespace
        if ( !is_string_whitespace( p ) )
        {
            printf( "Failure" );
            return 0;
        }

        printf( "Pass\n" );
        printf( "User entered only one number:\n%d\n", num1 );
    }
}

该程序现在正确地拒绝了上述输入:

代码语言:javascript
运行
复制
Susan 5 dslfhksdhfkl
Failure
代码语言:javascript
运行
复制
David 10 24 dslfhksdhfkl
Failure
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69780894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档