проблемы бесконечного быстрого цикла - PullRequest
0 голосов
/ 07 июля 2019

Моя программа предназначена только для приема входных данных. если 2 входа не являются целыми числами или имеется более 2 входов, предполагается, что вывести «Usange: Подмножество nk (n и k являются целыми числами, удовлетворяющими 0 <= k <= n <= 100)» и предложить пользователю повторить попытку , если я даю правильные входные данные, программа работает нормально, но если входные данные неверны, она печатается в бесконечном цикле. Я не знаю, почему первое «если» работает так, как я хотел, а второе «если» - нет. любая помощь очень ценится, спасибо. </p>

int main () {

int n;
int k;
int i = 1;
int B[MAX_SIZE + 1];

try_again:


printf("subsets ");

if (( scanf_s("%d %d", &n, &k) == 2) && ((k < n) && (n < 100))) {
    printSubsets(B, n, k, i);
    goto try_again;
}

if ((scanf_s("%d %d", &n, &k) != 2) || ((k > n) || (n > 100))) {
    printf("\n");
    printf("Usange: Subset n k (n and k are ints satisfying 0<=k<=n<=100)\n");

    goto try_again;
}

else { goto try_again; }

EXIT_SUCCESS;

здесь вывод после ввода 'e e'

Ответы [ 2 ]

0 голосов
/ 07 июля 2019

Одна проблема состоит в том, что %d не будет потреблять ничего, что не является частью действительной десятичной целочисленной константы - если вы введете нецифровый символ для ввода, %d никогда не удалит его из входного потока,и ваш код будет продолжать давать сбой на этом символе, что приведет к бесконечному циклу.

Если вы не можете гарантировать, что ваш ввод хорошо работает, то вам следует прочитать все как текст и проанализировать его вручную.Например:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define BUFSIZE 12 // 10 digits plus sign plus terminator

int getint( int *value, FILE stream)
{
  char inbuf[BUFSIZE] = {0};
  if ( fgets( inbuf, sizeof inbuf, stream ) )
  {
    char *chk;
    int tmp = strtol( inbuf, &chk, 10 );
    if ( isspace( *chk ) || *chk == 0 )
    { 
      *value = tmp;
      return 1;
    }
  }
  return 0;
}

Эта функция считывает до BUFSIZE -1 символов (или до следующей новой строки) из потока spcified с помощью функции fgets.Затем этот текст преобразуется в целочисленное значение, используя strtol, которое сохраняется в tmp.Переменная chk указывает на первый символ в строке, который не является частью действительной целочисленной константы (т. Е. Не является десятичным символом).Если этот символ - пробел или ноль, то строка является допустимым целым числом.Это целочисленное значение присваивается параметру value, и функция возвращает 1, чтобы указать успех.В противном случае value остается без изменений, и функция возвращает 0, чтобы указать на сбой.

Вы бы вызвали его из основной функции, например

if ( getint( &n, stdin ) && getint( &k, stdin ) && k < n && n < 100 )

Теперь давайте поговорим о структуре вашей программы....

Вы делаете scanf вызов дважды, что вам не нужно - ваш блок if/else может быть просто

if ( getint( &n, stdin ) && getint( &k, stdin ) && k < n && n < 100 )
  printSubsets(...);
else
  printf( “Usage...” );

Кроме того, пока естьслучаи, когда goto может быть правильным ответом, это не один из них.Вместо этого используйте цикл for(;;) для итерации, пока вы не выполните успешно printSubsets:

for (;;)
{
  printf( “subsets: ” );
  if ( getint( &n, stdin ) && getint( &k, stdin ) && k < n && n < 100 )
  {
    printSubsets(...);
    break;
  }
  else
    printf( “Usage...” );
}
0 голосов
/ 07 июля 2019

Вы вызываете scanf два раза, поэтому читаете 4 входа.Если вы хотите применить оба параметра if к «одному и тому же выводу scanf», вам нужно сохранить его.

Пример:

a = scanf_f(..);
if(a == "expression1") { ... }
if(a == "expression2") { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...