программа для определения того, задано или нет только целое число, в бесконечный цикл - PullRequest
0 голосов
/ 13 октября 2018
// program to detect whether only integer has been given or not
int main() {
    int a, b, s; 
    printf("Enter two proper number\n");
 BEGIN:
    s = scanf("%d %d", &a, &b); //storing the scanf return value in s
    if (s != 2) {
        printf("enter proper value\n");
        goto BEGIN;
    }
    printf("The values are %d and %d ", a, b);
}

Эта программа для определения того, было ли задано только целое число или нет, входит в бесконечный цикл при вводе недопустимых данных вместо запроса новых значений, почему goto не работает здесь?

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Обратите внимание, что когда scanf получает неправильный ввод (например, вы вводите cat dog ), этот ввод остается в буфере ввода до тех пор, пока вы не предпримете шаги для его очистки.Таким образом, цикл продолжает повторять и отклонять один и тот же ввод, который все еще там.

Проще использовать fgets и sscanf, и если сканирование не удается, вы просто забыли входную строку и получили другую.

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

int main(void) {
    int a, b;
    char str[42];
    do {
        printf("Enter 2 numeric values\n");
        if(fgets(str, sizeof str, stdin) == NULL) {
            exit(1);
        }
    } while(sscanf(str, "%d%d", &a, &b) != 2);
    printf("Numbers are %d and %d\n", a, b);
}

Программный сеанс:

Enter 2 numeric values
cat dog
Enter 2 numeric values
cat 43
Enter 2 numeric values
42 dog
Enter 2 numeric values
42 43
Numbers are 42 and 43

Обратите внимание, что goto является плохой практикой в ​​C и должен использоваться только там, где нет другого способа построения кода - который обычно есть.

0 голосов
/ 13 октября 2018

Существует несколько причин, по которым scanf() может возвращать значение, отличное от 2:

  • , существует ожидающий ввод, который не может быть преобразован в соответствии со спецификацией преобразования.Например, если во входном потоке есть ожидание A, преобразование %d завершится неудачно и A останется во входном потоке.Ваш код просто пытается выполнить это преобразование и никогда не остановится.Вы должны прочитать и отбросить неправильный ввод перед повторной попыткой.
  • во входном потоке произошла ошибка чтения или он достиг конца файла.Если хотя бы одно преобразование прошло успешно, возвращается число успешных преобразований, в противном случае возвращается EOF.Если возвращается EOF, нет смысла пытаться снова, так как больше ввод не будет доступен.
  • Обратите также внимание, что использование goto считается плохим стилем для конструкций, которые лучше выражены с помощью операторов управления потокомтакие как while и for.

Вот исправленная версия:

#include <stdio.h>

// program to detect whether only integer has been given or not
int main() {
    int a, b, s, c;

    printf("Enter two proper numbers: ");
    for (;;) {
        s = scanf("%d%d", &a, &b); //storing the scanf return value in s
        if (s == 2) // conversions successful
            break;
        if (s == EOF) {
            printf("unexpected end of file\n");
            return 1;
        }
        /* discard the rest of the input line */
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        printf("Invalid input. Try again: ");
    }
    printf("The values are %d and %d\n", a, b);
    return 0;
}
0 голосов
/ 13 октября 2018

scanf возвращает количество символов.В результате, s будет равно количеству написанных вами символов, равному 2, тогда ваш цикл остановится.Причина, по которой это выполняется бесконечно много раз, заключается в том, что количество введенных вами символов отличается от 2. Напечатайте s, чтобы увидеть, какое значение оно содержит, и вы получите больше информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...