бесконечный цикл в программе угадывания чисел в с - PullRequest
0 голосов
/ 12 сентября 2018

Я новичок в программировании на Си. Вот почему я работаю над тем, чтобы выполнять некоторые из более простых упражнений. Упражнение, над которым я работаю, - это игра «угадай число», в которой пользователь должен угадать число, лежащее между двумя числами (верхняя и нижняя границы). Программа делает то, что должна, за одним исключением: когда пользователь вводит символ вместо целого числа, программа застревает в бесконечном цикле. Единственный способ выйти из этого цикла - использовать оператор break и перезапустить программу. Вместо этого я хочу снова запросить программу для ввода данных пользователем, пока не будет введено целое число.

Может кто-нибудь сказать мне, почему программа застревает в этом бесконечном цикле и почему она не запрашивает ввод снова через scnanf, как это было в первой итерации? Ваша помощь будет оценена. спасибо.

//globals
int secret_nr;
int guess;
int upper_bound = 100;
int lower_bound = 1;
int total_guesses = 1;


void check_input(void) {
    if (guess < lower_bound || guess > upper_bound) {
        printf("Invalid input! Your guess must be between %d and %d\n", lower_bound, upper_bound);
    }
    else if (guess < secret_nr) {
        printf("Higher\n");
        total_guesses++;
    }
    else if (guess > secret_nr) {
        printf("Lower\n");
        total_guesses++;
    }
    else if (guess == secret_nr) {
        printf("correct! You guessed the number after guessing %d times!\n", total_guesses);
    }
}


int main(int argc, char* argv[]) {
    srand(time(NULL));
    secret_nr = (rand() % upper_bound) + 1;

    printf("Guess the number between %d and %d:\n", lower_bound, upper_bound);
    do {
        if (scanf("%d", &guess)) {
            check_input();
        }
        else {
            printf("Invalid input! Only integer values are allowed!\n");
            //break;
        }
    } while (guess != secret_nr);

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Я вижу этот ответ в другом сообщении: https://stackoverflow.com/a/1716066/5687321

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
}
0 голосов
/ 12 сентября 2018

Если scanf не сможет проанализировать свой ввод в соответствии с указанным форматом, то вход будет оставлен во входном буфере для следующего вызова scanf, который будет считывать тот же самый ввод и снова завершится ошибкой. И так далее, и так далее ...

Простое решение состоит в том, чтобы сначала прочитать всю строку ввода, используя, например, fgets. Затем вы можете использовать sscanf в этом (теперь извлеченном) вводе, чтобы попытаться проанализировать его.


Дальнейшее усложнение вашего текущего кода связано с тем, что если scanf не удастся каким-либо иным образом, он вернет EOF, которое является целым числом -1, что является "истиной". Это, конечно, приведет к проблемам с вашей логикой и зацикливанием.

...