scanf()行为不端

scanf()行为不端,c,scanf,C,Scanf,我有一个很短的片段,它是一个整数: #include <stdio.h> int main() { while (1) { int i = 0; int r = scanf("%d", &i); if (r == EOF) { printf("Error using scanf()\n"); } else if (r == 0) { printf("No

我有一个很短的片段,它是一个整数:

#include <stdio.h>

int main() {
    while (1) {
        int i = 0;
        int r = scanf("%d", &i);

        if (r == EOF) {
            printf("Error using scanf()\n");
        } else if (r == 0) {
            printf("No number found\n");
        } else {
            printf("The number you typed in was %d\n", i);
        }
    }
}
#包括
int main(){
而(1){
int i=0;
int r=scanf(“%d”和&i);
如果(r==EOF){
printf(“使用scanf()时出错\n”);
}else如果(r==0){
printf(“未找到编号”);
}否则{
printf(“您键入的号码是%d\n”,i);
}
}
}
但问题是,如果我输入任何字母,它只会不断循环并打印“未找到编号”,而不是等待下一次输入


我做错了什么?

听起来好像您没有清除输入缓冲区,而是让不正确的字符反复扫描。
请参见此处:



听起来好像您没有清除输入缓冲区,而是将不正确的字符反复扫描。
请参见此处:



使用
scanf
时,如果您尝试执行读取操作,但发现的数据与预期格式不匹配,
scanf
会留下未知数据,供将来的读取操作拾取。在本例中,发生的情况是,您试图从用户读取格式化数据,用户的数据与预期格式不匹配,因此它无法读取任何内容。然后,它循环尝试再次阅读,并找到与以前相同的令人不快的输入,然后再次循环,等等

要解决这个问题,您只需要使用使输入变得混乱的字符。一种方法是调用
fgetc
读取字符,直到检测到换行符,这将刷新任何有问题的字符:

while (1) {
    int i = 0;
    int r = scanf("%d", &i);

    if (r == EOF) {
        printf("Error using scanf()\n");
    } else if (r == 0) {
        printf("No number found\n");

        /* Consume bad input. */
        while (fgetc(stdin) != '\n')
            ;

    } else {
        printf("The number you typed in was %d\n", i);
    }
}

希望这有帮助

使用
scanf
时,如果您尝试执行读取操作,但发现的数据与预期格式不匹配,
scanf
将保留未知数据,以供将来的读取操作拾取。在本例中,发生的情况是,您试图从用户读取格式化数据,用户的数据与预期格式不匹配,因此它无法读取任何内容。然后,它循环尝试再次阅读,并找到与以前相同的令人不快的输入,然后再次循环,等等

要解决这个问题,您只需要使用使输入变得混乱的字符。一种方法是调用
fgetc
读取字符,直到检测到换行符,这将刷新任何有问题的字符:

while (1) {
    int i = 0;
    int r = scanf("%d", &i);

    if (r == EOF) {
        printf("Error using scanf()\n");
    } else if (r == 0) {
        printf("No number found\n");

        /* Consume bad input. */
        while (fgetc(stdin) != '\n')
            ;

    } else {
        printf("The number you typed in was %d\n", i);
    }
}
希望这有帮助

手册页上说

返回值 这些函数返回分配的输入项目数。这可能会小于中提供的值,甚至为零 匹配失败的事件零表示虽然有可用的输入,但没有分配转换;典型- 从逻辑上讲,这是由于输入字符无效,例如用于“%d”转换的字母字符。

因为您已经使用了“%d”,如果您使用任何数字,那么这将正常工作,否则它将不会从缓冲区中使用它

返回值 这些函数返回分配的输入项目数。这可能会小于中提供的值,甚至为零 匹配失败的事件零表示虽然有可用的输入,但没有分配转换;典型- 从逻辑上讲,这是由于输入字符无效,例如用于“%d”转换的字母字符。


由于您使用了“%d”,如果您使用任何数字,那么这将正常工作,否则它将不会从缓冲区消耗它

最好有一个无用的缓冲区传递给对
fgets
的调用以完成该行。最好还是从一开始就使用
fgets
。最好有一个无用的缓冲区传递给调用
fgets
来完成这一行。最好从一开始就使用
fgets