如何使用 scanf 无限循环处理不正确的输入?

How to handle incorrect input with an infinite loop using scanf?

我正在努力想出一个我要自己完成的问题的解决方案,我尝试了多种不同的方法,但我似乎无法让它正常运行。

我正在尝试做的是在用户在 scanf 中输入非数字字符时进行处理。最终目标是让程序向用户询问一个系列的值,并一直询问直到输入浮点数或整数,然后完成系列。

既然是个小节目,就post整件事吧。非常感谢任何帮助。

int main(void) {
    int numberOfValues, ctr, inputValidation, avg;
    float sum = 0;

    printf("\nHow many values are you averaging?: ");
    scanf("%d", &numberOfValues);

    float inputValue[numberOfValues];

    printf("\n");

    for (ctr = 0; ctr < numberOfValues; ctr = ctr + 1) {
        printf("\tPlease enter value %d: ", ctr + 1);
        inputValidation = scanf("%f", &inputValue[ctr]);
        if (inputValidation != 1) {
            printf("\tPlease enter value %d again: ", ctr + 1);
            scanf("%f", &inputValue[ctr]);
        } else {
            sum += inputValue[ctr];
        }
    }

    avg = sum / numberOfValues;

    printf("\nYour average is: %g", avg);

    return 0;
}

您需要消耗“坏”数据。由于 scanf() 无法匹配您请求的格式,它将把数据留在缓冲区中。

使用 getchar() 作为一种方式:

            int gc;
            do {
                gc = getchar();
                if (gc == EOF) exit(EXIT_FAILURE);
            } while(gc != '\n');

这是您为此修改的程序。 免责声明:以下程序仅帮助解决特定问题。它是不完整的,还有其他挑战和场景需要克服。例如。尝试以数字开始输入并添加非数字字符,例如“4abc”,看看会发生什么。更多问题示例在评论中。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int numberOfValues, ctr, avg;
    float sum = 0;

    printf("\nHow many values are you averaging?: ");
    scanf("%d", &numberOfValues);

    float inputValue[numberOfValues];

    printf("\n");

    for (ctr = 0; ctr < numberOfValues; ctr = ctr + 1)
    {
        printf("\tPlease enter value %d: ", ctr + 1);

        while (scanf("%f", &inputValue[ctr]) != 1) {
            int gc;
            do {
                gc = getchar();
                if (gc == EOF) exit(EXIT_FAILURE);
            } while(gc != '\n');
            printf("\tPlease enter value %d again: ", ctr + 1);
        }
        sum += inputValue[ctr];
    }

    avg = sum / numberOfValues;

    printf("\nYour average is: %d", avg);

    return 0;
}

您需要在尝试再次调用 scanf 之前丢弃 'bad' 数据。有多种方法可以做到这一点。您可以丢弃下一个换行符之前的所有内容(scanf("%*[^\n]") 会这样做),但您可能还应该在某处检查 EOF。或者您可以丢弃单个字符并重试(但您可能不想再次提示,因为您可能在输入缓冲区中留下了多个字符。)