Scanf не читает ввод - PullRequest
       2

Scanf не читает ввод

1 голос
/ 13 марта 2011

Я прочитал больше веток о scanf и нашел несколько ответов, но никто не помог мне:

while(!comanda){
    int tmp;
    if (scanf("%d", &tmp) == 0)
        getchar();
    else{
        comanda = tmp;
        fprintf(stdout,"%d",&comanda);
        fflush(stdout);}
    }
}

Проблема в том, что после выполнения этих строк кода ничего не происходит. После этого я проверяю команду, которая не выполняется.

Ответы [ 2 ]

2 голосов
/ 13 марта 2011

Одна из проблем с scanf и всеми отформатированными функциями ввода заключается в том, что терминалы, как правило, работают в режиме линии или режиме приготовления , а API предназначен для режима raw , Другими словами, реализации scanf обычно не возвращаются, пока не встретится перевод строки. Вход буферизуется, и будущие вызовы scanf будут использовать буферизованную строку. Рассмотрим следующую простую программу:

#include <stdio.h>

int main() {
    int a_number;
    printf("Enter a number: ");
    fflush(stdout);
    while (scanf("%d", &a_number) != EOF) {
        printf("you entered %d\n", a_number);
        printf("Enter another number: ");
        fflush(stdout);
    }
    return 0;
}

Вы можете ввести несколько цифр перед нажатием return . Вот пример запуска этой программы.

bash$ gcc foo.c
bash$ ./a.out
Enter a number: 1 2 3 4 5 6 7 8 9 10<Return>
you entered 1
Enter another number: you entered 2
Enter another number: you entered 3
Enter another number: you entered 4
Enter another number: you entered 5
Enter another number: you entered 6
Enter another number: you entered 7
Enter another number: you entered 8
Enter another number: you entered 9
Enter another number: you entered 10
Enter another number: <Ctrl+D>bash$ 
bash$

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

Альтернативой этому является использование fgets и одновременная обработка целых строк данных или интерфейс терминала для отключения «обработки канонического ввода» . Большинство людей используют fgets, поскольку раздел интерфейса терминала POSIX не реализован в Windows.

0 голосов
/ 13 марта 2011

Ваш scanf("%d", &tmp) может вернуть одно из 3 значений

  • если он возвращает 1, это означает, что значение было прочитано и помещено в tmp
  • если он возвращает 0, это означает, что в буфере был плохой символ (который вы обнаружите и избавитесь с помощью следующего getchar())
  • если возвращается EOF, это означает, что stdin находится в состоянии конца файла. Независимо от того, сколько getchar() s вы делаете, условие «конец файла» не исчезнет, ​​и вы застрянете в бесконечном цикле.

Также проверьте возвращаемое значение из scanf для EOF.

while(!comanda){
    int tmp;
    int ret;
    ret = scanf("%d", &tmp);
    if (ret == 0)
        getchar();
    else if (ret == EOF){
        perror("stdin end-of-file");
        break; /* get out of the loop */
    }
    else {
        comanda = tmp;
        fprintf(stdout,"%d",comanda); /* & is an error */
        fflush(stdout);}
    }
}

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

...