我是C初学者,我正在尝试创建一个使用用户输入的程序。 问题是当用户输入不正确的数据时,程序以无限错误循环结束(说“输入数据不正确”)。 我尝试了fflush并用空字符串清除用户输入,但它只是以某种方式不起作用。
MAIN.C:
#include <stdio.h>
#include "nd.h"
#include "nsd.h"
int num1;
int num2;
int a;
//char *p;
int main()
{
while(!feof(stdin))
{
if(scanf("%d %d",&num1,&num2)==2)
{
if ((nd(num1)==1) && (nd(num2)==1))
{
printf("%s\n", "prime");
}
else
{
a=nsd(num1, num2);
printf("%d\n", a);
}
}
else
{
fprintf(stderr, "Incorrect input data...");
//fflush(stdin);
//scanf ("%s",p);
}
}
printf("%s\n", "DONE");
return 1;
}
nd.c:
#include "nd.h"
#include <math.h>
#include <stdlib.h>
int nd(int a) {
// calculate greatest divisor of "a"
// nd equals 1, if it is prime
int ret;
int min_sqrt;
if (a == 1) {
ret = 1;
} else {
min_sqrt = abs(a) / 2;
for (ret=min_sqrt; ret>1; ret--) {
if ((a % ret)==0) {
break;
}
}
}
return ret;
}
答案 0 :(得分:1)
发生此问题的原因是对scanf("%d %d",...)
的调用仅匹配由空格分隔的两个整数。其他任何内容都将保留在输入缓冲区中。如果你的程序在没有清除缓冲区的情况下循环,那么同样的事情会再次发生。
您可以通过取消注释scanf("%s",p);
并将char *p;
更改为char p[100];
之类的内容来解决此问题,以便此scanf()
调用实际上可以放置结果。
然而,这不是一个理想的解决方案。格式字符串%s
在调用scanf()
时本质上是不安全的,因为它将匹配任意长度的非空白字符序列。这意味着无论您使p[]
缓冲区有多大,您的程序都容易受到缓冲区溢出的影响。
您当然可以通过使用%99s
等格式字符串限制输入长度来解决此问题。但是在处理交互式用户输入时,通常最好采用不同的方法,例如:
#include <stdlib.h>
char input[100], *end1, *end2;
int num1, num2, accept;
:
while (1) {
scanf("%99s",input);
num1 = strtol(input,&end1,10);
scanf("%99s",input);
num2 = strtol(input,&end2,10);
if (*end1 || *end2) puts("Illegal input :( Try again");
else break;
}