首页 > 解决方案 > C:scanf 没有在无限循环中停止

问题描述

当输入类型不是整数时,我想实现一个简单的代码来打印错误消息。

下面是一个示例代码。

int num;
while (1) {
    printf("Input the value of integer: ");
    int result = scanf(" %d", &num);
    if (result == 0) {
        printf("ERROR-Not an integer.\n");
    }
    else if (num < 0) {
         printf("ERROR- Not positive.\n");    
    }else{ 
        break;   
    }
}

在这段代码中,如果值不是整数,“scanf”会询问数字。

但是,当输入不是整数时,此函数不会中断。

也许问题是缓冲区上的值。“fflush”将是解决方案,但我不想使用它。

标签: cwhile-loopscanf

解决方案


问题是你没有清空匹配stdin的失败案例。您正在寻找整数输入。如果用户输入的不是整数,则会发生匹配失败。当匹配失败发生时,从停止中提取字符并且导致匹配失败的字符留在输入缓冲区(此处)未读- 如果您尝试再次读取而不先清除,则等待再次咬你......如果你是循环输入——好吧,你知道会发生什么……stdinstdinstdin

(亲爱的......我试图阅读一个int但它失败了,我一直在尝试并且它一直失败 - 帮助??)

如何解决?

很简单,你必须在匹配失败stdin后清空。你比大多数人做得更好——你正在检查 return,但你还有一个难题要添加——一个简单的函数可以在发生匹配失败时使用。一种非常便携且非常简单的方法是简单地提取所有字符,直到遇到换行符或遇到换行符,例如:empty_stdin()EOF

void empty_stdin(void) {
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

在您的示例中将所有部分放在一起,您可以执行以下操作:

#include <stdio.h>

void empty_stdin(void) {
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

int main (void) {
    int num;
    while (1) {
        printf("Input the value of integer: ");

        int result = scanf(" %d", &num);

        if (result == EOF) {    /* handle ctrl+d (ctrl+z on win) */
            printf (" user canceled input (manual EOF)\n");
            break;
        }
        else if (result == 0) { /* matching failure */
            printf("ERROR-Not an integer.\n");
            empty_stdin();      /* remove offending characters */
        }
        else if (num < 0) {
            printf ("ERROR- Not positive.\n");    
        }
        else        /* positive number enetered */
            break;
    }

    return 0;
}

@David Bowling已经在评论中解释了前导space" %d"不必要的,因为所有数字转换都会消耗前导空格)

示例使用/输出

$ ./bin/scanf_empty
Input the value of integer: foo
ERROR-Not an integer.
Input the value of integer: -1
ERROR- Not positive.
Input the value of integer: bar
ERROR-Not an integer.
Input the value of integer: 1

测试手册EOF案例(用户按下Ctrl+d(或Ctrl+z窗口)

$ ./bin/scanf_empty
Input the value of integer:  user canceled input (manual EOF)

如果您还有其他问题,请仔细查看并告诉我。


推荐阅读