【问题标题】:C programming - Repeat scanf until only numbers are inputC 编程 - 重复 scanf 直到只输入数字
【发布时间】:2013-10-16 01:53:49
【问题描述】:

我不想做的是检查我的输入是否是数字然后继续,否则打印出错误的格式并要求新的输入。我得到的是一个无限循环打印“错误格式”

这是我输入数字的函数:

void input_number(int *number)
{

    printf("Number: ");

    if ( scanf("%d", number) == 1 )
        return 0;
    else
    {
        printf("-> Wrong format, try again! <-\n");
        input_number(number); // start over
    }
}

当我运行程序时,我希望它看起来像这样:

号码:你好

-> 格式错误,重试!

数量:4

然后继续……

【问题讨论】:

  • 不是问题的原因,但您不想使用递归来重试。此外,无论您是否成功输入数字,您都在重新拨打input_number。您的 else 子句周围缺少括号 ({})。

标签: c function scanf


【解决方案1】:

试试这个:(注意有很多更好的方法可以做到这一点)

void input_number(int *number)
{
    int flag=1;
    printf("Number: ");

    while(flag==1){
        if ( scanf("%d", &number) == 1 ){ // also you were missing & specifier
            flag = 0;
            //return 0;
        }else{
            printf("-> Wrong format, try again! <-\n");
            getchar(); // to catch the enter from the input -- make sure you include stdlib.h

        }
    }

    return 0;
}

输出:

Number: f
-> Wrong format, try again! <-
Number: f
-> Wrong format, try again! <-
Number: d
-> Wrong format, try again! <-
Number: d
-> Wrong format, try again! <-
Number: s
-> Wrong format, try again! <-
Number: s
-> Wrong format, try again! <-
Number: s
-> Wrong format, try again! <-
Number: s
-> Wrong format, try again! <-
Number: 6

【讨论】:

  • 仍然给我一个无限循环的打印速度,因为它不是一个数字。
  • @Zn3 Yeh 自己运行了它.. 代码现在已修复以补偿输入后的输入
【解决方案2】:

我认为问题在于,如果 scanf() 由于 EOF 或输入流中存在非数字字符而失败,那么当您下次调用它时,该问题仍然存在,因此它再次失败,并且继续直到程序耗尽资源或您耗尽耐心。

至少,你需要区分:

  1. 好的
  2. EOF(无需阅读更多内容)
  3. 错误(需要阅读更多内容,但下一个字符至少不是数字的一部分)

如果您希望每行有一个数字,那么最好使用fgets()sscanf()。如果您对每行多个数字感到满意,那么您必须更加努力。您可能还应该从函数中返回一个值来指示它是否成功。

int input_number(int *number)
{
    char line[4096];

    while (printf("Number: ") > 0 && fgets(line, sizeof(line), stdin) != 0)
    {
        if (sscanf(line, "%d", number) == 1)
            return 0;
        printf("-> Wrong format, try again! <-\n");
    }
    return EOF;
}

int input_number(int *number)
{
    while (printf("Number: ") > 0 && scanf("%d", number) != 1)
    {
        int c;
        if (feof(stdin) || ferror(stdin))
            return EOF;
        printf("-> Wrong format, try again! <-\n");
        while ((c = getchar()) != EOF && c != '\n')
            ;
        if (c == EOF)
            return EOF;
    }
    return 0;
}

注意feof()的正确使用; I/O 操作失败,代码需要区分 EOF 和 I/O 错误以及格式错误。

在第二个函数中,如果printf() 失败,则会错误地告知您读取了一个数字。如果这是一个问题,请添加额外的测试,但该代码已经比使用 fgets() 的代码更难编写,因此在决定使用它时要谨慎。

请注意,原始代码在返回void 的函数中包含return 0;。该代码应该已被编译器拒绝。

【讨论】:

  • 感谢您的详细解答和解释!
【解决方案3】:

尝试使用检查用户输入并尝试将其解析为 int 的循环。如果不成功,它可以一直要求用户输入,直到他们输入一个实际的 int。

【讨论】:

    【解决方案4】:

    此时您可能知道您的代码中几乎没有缺陷,递归并不是最好的主意。这是一种让您的代码工作的尝试,无论漂亮与否。

    void input_number(int *number)
    {
    
        printf("Number: ");
    
        if ( scanf("%d", number) == 1 )
            return 0;
        else
        {
            scanf("%*s"); /* <--this will read and discard whatever caused scanf to fail */
            printf("-> Wrong format, try again! <-\n");
            input_number(number); // start over
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 2013-02-18
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 2016-08-16
      相关资源
      最近更新 更多