如何检查scanf()在C中是否正常工作?

时间:2015-11-18 02:07:41

标签: c

我试图看看用户是否输入了3个正确的输入。如果不是,循环会一次又一次地请求输入,直到他们正确地纠正它为止。

#include <stdio.h>
int main(void) {

        int num1,num2;
        char str;
        int check;

        printf("Enter : ");
        check = scanf("%d,%d, %c", &num1, &num2, &str);

        while (check != 3) {

                 printf("Enter : ");
                 check = scanf("%d,%d, %c", &num1, &num2, &str);
        }


}

让我们说如果我输入a, 5.4, c,我们就会得到一个无限循环。为什么它会给出无限循环?

2 个答案:

答案 0 :(得分:1)

有很多方法可以在正确的循环中错误地使用scanf。主要问题(除了手册页中解释的输入匹配失败),无法清空输入缓冲区({{ 1}}在转换失败后从终端读取时。 (还有一个问题是用户必须输入内容。)当用户输入文本并按stdin时,会生成[Enter]newline)并将其放入输入缓冲区以标记行结束。当您输入'\n'时,a, 5.4, c没问题,但'a'不是5.4且处理失败:

  

如果指令的处理失败,则不再读取其他输入,并且   scanf()返回。

int返回时,它会将剩余的字符留在scanf中并循环并尝试再次阅读。 stdin尝试阅读scanf中剩余的内容,再次处理失败,循环继续无休止。

在这种情况下,防止无限循环的唯一方法是在调用stdin后手动清空输入缓冲区。简单的事情会做:

scanf

这将确保您在下一次迭代时以空缓冲区开始。例如:

int c;
...
while (...) {
    scanf (...)
    while ((c = getchar()) != '\n' && c != EOF) {}
}

使用示例

#include <stdio.h>

int main (void) {

    int num1 ,num2, c;
    char str;

    while (printf ("\nEnter : ") && 
           scanf (" %d, %d, %c%*c", &num1, &num2, &str) != 3) {
        printf ("error: invalid input, required: 'int, int, char'\n");

        /* empty remaining chars from input buffer */
        while ((c = getchar()) != '\n' && c != EOF) {}
    }

    printf ("\n num1 : %d\n num2 : %d\n str  : %c\n\n", num1, num2, str);

    return 0;
}

注意:这不能防止用户输入任何内容(只需按$./bin/scanf3 Enter : a error: invalid input, required: 'int, int, char' Enter : a, 5.4, c error: invalid input, required: 'int, int, char' Enter : 10, 25 error: invalid input, required: 'int, int, char' Enter : 10, 25, a num1 : 10 num2 : 25 str : a )并且光标只是在等待输入时闪烁。这是[Enter]的固有行为,其中一部分原因是面向行的输入法(scanffgets)在获取输入时更为可取。

答案 1 :(得分:-1)

第一次scanf()读取字符然后它读取换行符(输入/空白字符)。这个字符出现在输入缓冲区中,由scanf()函数读取。

在使用fflush(stdin)读取新用户输入之前清除缓冲区。

编辑:在Windows VS2013中测试过。我没有Linux。 Windows和Linux以不同的方式定义fflush()的行为。如果您在Windows平台中使用:

int main(void) {

    int num1, num2;
    char str;
    int check;

    printf("Enter : ");
    check = scanf("%d,%d, %c", &num1, &num2, &str);

    while (check != 3) {

////Flush the input buffer ////

        fflush(stdin);
        printf("Enter : ");
        check = scanf("%d,%d, %c", &num1, &num2, &str);
    }

}

编辑:这适用于所有平台。

另一种简单的方法是通过

消耗剩余的读取行
while ((c = getchar()) != '\n' && c != EOF);

所以现在

int main(void) {

    int num1, num2;
    char str,c;
    int check;

    printf("Enter : ");
    check = scanf("%d,%d, %c", &num1, &num2, &str);

    while (check != 3) {

        ////read the remaining char ////
        while ((c = getchar()) != '\n' && c != EOF);

        printf("Enter : ");
        check = scanf("%d,%d, %c", &num1, &num2, &str);
    }
}