我有一个小的C程序,它只是从stdin读取数字,每个循环周期一个.如果用户输入了一些NaN,则应该向控制台输出错误,输入提示应该再次返回.输入"0"时,循环应该结束,给定的正/负值的数量应该打印到控制台.这是程序:
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
printf("Err...\n");
continue;
}
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,在输入一些非数字(如"a")时,这会导致无限循环一遍又一遍地写" - > Err ...".我想这是一个scanf()问题,我知道这个函数可以被更安全的替换,但这个例子适用于初学者,只知道printf/scanf,if-else和循环.
我已经阅读了这个问题的答案并浏览了其他问题,但没有真正回答这个具体问题.
jer*_*son 36
scanf仅使用与格式字符串匹配的输入,返回消耗的字符数.任何与格式字符串不匹配的字符都会导致它停止扫描并使无效字符仍在缓冲区中.正如其他人所说,在继续之前,仍然需要从缓冲区中清除无效字符.这是一个非常脏的修复,但它将从输出中删除有问题的字符.
char c = '0';
if (scanf("%d", &number) == 0) {
printf("Err. . .\n");
do {
c = getchar();
}
while (!isdigit(c));
ungetc(c, stdin);
//consume non-numeric chars from buffer
}
Run Code Online (Sandbox Code Playgroud)
编辑:修复代码以一次性删除所有非数字字符.不再为每个非数字字符打印多个"Errs".
这是一个非常好的scanf概述.
我想你只需要在继续循环之前刷新缓冲区.这样的事情可能会起作用,虽然我无法测试我在这里写的东西:
int c;
while((c = getchar()) != '\n' && c != EOF);
Run Code Online (Sandbox Code Playgroud)
scanf()将" a"仍留在输入缓冲区中以供下次使用.你应该用它getline()来读取一行,无论如何,然后用它strtol()或类似的方式解析它.
(是的,getline()是特定于GNU的,而不是POSIX.那么什么?问题是标记为"gcc"和"linux". getline()也是读取文本行的唯一合理选项,除非您想手动完成所有操作.)