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

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

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

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


person Octavian    schedule 13.03.2011    source источник
comment
fprintf(stdout,"%d",&comanda); - & там быть не должно. Просто как примечание.   -  person dialer    schedule 13.03.2011
comment
пожалуйста, будьте более конкретными. где код останавливается, когда вы говорите, что ничего не происходит? где блокирует?   -  person Mat    schedule 13.03.2011
comment
Отредактировано. Теперь это должно иметь смысл.   -  person Octavian    schedule 13.03.2011
comment
Чему изначально равна команда?   -  person jonsca    schedule 13.03.2011
comment
Изначально команда равна нулю. Это проблема с тем, что scanf принимает новую строку в буфере или что-то в этом роде.   -  person Octavian    schedule 13.03.2011


Ответы (2)


Одна из проблем с scanf и всеми функциями форматированного ввода заключается в том, что терминалы обычно работают в линейный или готовый режим, а API предназначен для необработанного режима. Другими словами, реализации 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.

person D.Shawley    schedule 13.03.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().

person pmg    schedule 13.03.2011