C - 无限错误循环(新手)

时间:2014-11-21 09:37:40

标签: c

我是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;
}

1 个答案:

答案 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;
}

另请阅读this item in the comp.lang.c FAQ.