Почему этот цикл getchar () останавливается после ввода одного символа? - PullRequest
3 голосов
/ 17 марта 2010
#include <stdio.h>

int main() {
    char read = ' ';

    while ((read = getchar()) != '\n') {
        putchar(read);
    }

    return 0;
}

Мой ввод f (за которым, конечно, следует ввод). Я ожидаю, что getchar() снова запросит ввод, но вместо этого программа завершается. Как так? Как я могу это исправить?

Ответы [ 5 ]

7 голосов
/ 17 марта 2010

Терминал иногда может быть немного запутанным. Вы должны изменить свою программу на:

#include <stdio.h>

int main() {
    int read;
    while ((read = getchar()) != EOF) {
        putchar(read);
    }
    return 0;
}

Это будет читать до тех пор, пока getchar не прочитает EOF (большую часть времени этот макрос расширяется до -1) из терминала. getchar возвращает int, поэтому вы должны превратить вашу переменную «read» в целое число, чтобы вы могли проверить EOF. Вы можете отправить EOF из вашего терминала в Linux с помощью ^ D, и я думаю, что в Windows с ^ Z (?).

Чтобы немного объяснить, что происходит. В вашей программе выражение

(read = getchar()) !='\n'

будет истинным, если из буфера не читается '\ n'. Проблема в том, чтобы получить буфер для вашей программы, вы должны нажать Enter, что соответствует '\ n'. Следующие шаги выполняются, когда ваша программа вызывается в терминале:

~$\a.out

это запускает вашу программу

(empty line)                    

getchar () совершил системный вызов для получения ввода от терминала, и терминал принимает

f                   

вы сделали ввод в терминале. 'F' записывается в буфер и возвращается обратно на терминал, ваша программа еще не имеет представления о символе.

f
f~$                 

Вы нажали ввод. Ваш буфер содержит теперь 'f \ n'. «Enter» также сигнализирует терминалу, что он должен вернуться в вашу программу. Ваша прога читает буфер и находит f и выводит его на экран, а затем находит '\ n' и немедленно останавливает цикл и завершает вашу программу.

Это будет стандартное поведение большинства терминалов. Вы можете изменить это поведение, но это будет зависеть от вашей ОС.

2 голосов
/ 17 марта 2010

getchar () возвращает следующий символ из входного потока. включает , конечно, также переводы строк и т. Д. Тот факт, что вы не видите прогресса в цикле, пока вы не нажмете «Enter», вызван тем, что ваш файловый ввод-вывод (работающий на stdin) не ' Передайте входной буфер функции getchar (), если он не обнаружит '\ n' в конце буфера. Ваша подпрограмма сначала блокирует, а затем обрабатывает два нажатия клавиш в один прием, заканчивая, как вы указали, появлением '\ n' во входном потоке. Facit: getchar () не удалит '\ n' из входного потока (зачем это нужно?).

1 голос
/ 17 марта 2010

Вы запрограммировали его так, чтобы цикл завершался, когда вы читаете \ n (ввод), а затем возвращаете 0; из основного, который выходит из программы.

Возможно, вы хотите что-то вроде

 while ((read = getchar()) != EOF) {
        putchar(read);
    }
1 голос
/ 17 марта 2010

после f вы вводите «enter», что означает «/ n». поэтому цикл заканчивается там. если вы хотите взять другой символ, просто продолжайте помещать их один за другим, как только нажата клавиша enter, цикл завершается.

0 голосов
/ 18 марта 2010

На n x терминалах вы можете нажать Control-D, который скажет tty драйверу вернуть входной буфер в приложение, читающее его. Вот почему ^ D в новой строке заканчивает ввод - это заставляет tty возвращать нулевые байты, которые приложение интерпретирует как конец файла. Но это также работает в любом месте строки.

...