Ввод C - getchar()

Это основной вопрос .. но должен был спросить. Для такой программы, если вариант использования 123 ^ Z, программа не завершится, даже если я поставлю EOF в конце (Ctrl + Z). Почему это так? Это работает только тогда, когда я помещаю EOF после CR. Любые ответы будут оценены. Спасибо.

#include < stdio.h>

void main()
{
    int i, nc;

    nc = 0;
    i = getchar();
    while (i != EOF) {
        nc = nc + 1;
        i = getchar();
    }
    printf("Number of characters in file = %d\n", nc);
}

person Iceman    schedule 20.03.2012    source источник
comment
Какая платформа? ^Z заставляет меня думать о Windows, но было бы неплохо, если бы вы отметили вопрос своей платформой. Спасибо.   -  person sarnold    schedule 21.03.2012
comment
Что произойдет, если вы поместите CR после EOF?   -  person asaelr    schedule 21.03.2012
comment
Такое же поведение под Linux с ^D. Работает только если на новой строке   -  person paul    schedule 21.03.2012
comment
Короткий ответ: так работает Windows. Обратите внимание, однако, что если вы нажмете F6 вместо Ctrl + Z, это вступит в силу, даже если оно находится в середине строки.   -  person Jerry Coffin    schedule 21.03.2012
comment
возможный дубликат k&R, как getchar читает EOF   -  person LihO    schedule 21.03.2012


Ответы (1)


В Windows сочетание клавиш Ctrl-Z действует только в том случае, если оно нажато в начале строки. В противном случае ОС игнорирует его. Вы должны нажать «ввод» или «возврат», чтобы сначала вставить символ новой строки.

В Unix сочетание клавиш Ctrl-D немедленно сбрасывает stdin (как указано в комментариях ниже), но не заставит getchar() возвращать EOF, если только вы не находитесь на новой пустой строке; так же, как в винде.

Из комментариев (ниже):

В Unix нет «символа EOF». EOF — это просто чтение нулевой длины. Это происходит в конце обычных файлов и может быть принудительно запущено на терминале нажатием управляющего символа, установленного в настройках терминала для EOF (обычно ^D). Причина, по которой ^D "не работает", когда буфер терминала не пуст, заключается в том, что на самом деле он ничего не вставляет в поток; это просто вызывает возврат ожидающего чтения, но, поскольку длина ввода отлична от нуля, приложение не обрабатывает его как «EOF».

Это решает хорошую проблему — на самом деле ни один файл не содержит EOF — и нажатие Ctrl-D не будет «вставлять» (как я уже говорил ранее) что-либо в поток stdin. Он просто сбрасывает stdin. EOF — это стандартный макрос, представляющий уведомление о достижении конца файла стандартной функцией.

Благодаря @R. за объяснение о EOF.

person Chris Browne    schedule 20.03.2012
comment
Не совсем. Хотя ^D работает внутри строки, чтобы сбросить STDIN, он не сразу закрывает STDIN. - person Niklas B.; 21.03.2012
comment
Моя система (Debian, по общему признанию, не Unix) ведет себя не так, как вы описываете. Нажатие Ctrl+D в середине строки имеет очевидный эффект ввода без ввода. - person pmg; 21.03.2012
comment
Спасибо за комментарий, Никлас. Я обновил свой ответ соответственно. - person Chris Browne; 21.03.2012
comment
В Unix нет символа EOF. EOF — это просто чтение нулевой длины. Это происходит в конце обычных файлов и может быть принудительно запущено на терминале нажатием управляющего символа, установленного в настройках терминала для EOF (обычно ^D). Причина, по которой ^D не работает, когда буфер терминала не пуст, заключается в том, что он фактически ничего не вставляет в поток; это просто вызывает возврат ожидающего чтения, но, поскольку длина ввода отлична от нуля, приложение не обрабатывает его как EOF. - person R.. GitHub STOP HELPING ICE; 21.03.2012