Как работает getchar()?
Меня смущает программа, упомянутая в K & R, которая использует getchar()
. Он дает тот же результат, что и входная строка:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
}
Почему он печатает всю строку? Я ожидаю, что он прочитает символ и снова попросит ввести.
И все ли строки, которые мы вводим, заканчиваются EOF?
Ответы
Ответ 1
В простой настройке, которую вы, вероятно, используете, getchar
работает с буферизованным вводом, поэтому вам нужно нажать enter, прежде чем getchar получит что-нибудь, что нужно прочитать. Строки не заканчиваются на EOF
; на самом деле, EOF
на самом деле не является символом, а магическим значением, указывающим конец файла. Но EOF
не является частью прочитанной строки. Это то, что getchar
возвращает, когда читать нечего.
Ответ 2
Существует базовый буфер/поток, который getchar() и друзья читают. Когда вы вводите текст, текст где-то хранится в буфере. getchar() может передавать через него по одному символу за раз. Каждое чтение возвращает следующий символ до тех пор, пока он не достигнет конца буфера. Причина, по которой он не просит вас о последующих символах, состоит в том, что он может извлечь следующий из буфера.
Если вы запустите свой script и введите прямо в него, он будет продолжать запрашивать ввод для ввода, пока не нажмете CTRL + D (конец файла). Если вы называете это как. /program < myInput, где myInput - текстовый файл с некоторыми данными, он получит EOF, когда он достигнет конца ввода. EOF не является символом, который существует в потоке, но имеет значение дозорного, чтобы указать, когда достигнут конец ввода.
В качестве дополнительного предупреждения, я считаю, что getchar() также вернет EOF, если он встретит ошибку, поэтому вы захотите проверить ferror(). Пример ниже (не проверен, но вы поняли).
main() {
int c;
do {
c = getchar();
if (c == EOF && ferror()) {
perror("getchar");
}
else {
putchar(c);
}
}
while(c != EOF);
}
Ответ 3
Строки, по определению C
, заканчиваются на '\0'
. У вас нет "C strings"
в вашей программе.
Ваша программа считывает символы (буферизованные до ENTER) со стандартного ввода (клавиатура) и записывает их обратно на стандартный вывод (экран). Он делает это независимо от того, сколько символов вы вводите или сколько времени вы это делаете.
Чтобы остановить программу, вы должны указать, что в стандартном вводе нет данных (а как у клавиатуры нет больше данных?).
Просто введите Ctrl+D
(Unix) или Ctrl+Z
(Windows), чтобы притвориться, что файл достиг своего конца.
Ctrl+D
(или Ctrl+Z
) не являются символами в значении слова C
.
Если вы запускаете свою программу с перенаправлением ввода, EOF является фактическим концом файла, а не верой.
./a.out < source.c
Ответ 4
getchar() считывает один символ ввода и возвращает этот символ как значение функции. Если ошибка чтения символа или если конец ввода достигнут, getchar() возвращает специальное значение, представленное "EOF".
Ответ 5
В соответствии с определением getchar() он считывает символ из стандартного ввода. К сожалению, stdin ошибочно принимается за клавиатуру, что может быть не так для getchar. getchar использует буфер как stdin и одновременно считывает один символ. В вашем случае, поскольку EOF отсутствует, getchar и putchar работают несколько раз, и он выглядит так, как будто вся строка печатается за раз. сделайте небольшое изменение, и вы поймете:
putchar(c);
printf("\n");
c = getchar();
Теперь посмотрите на результат по сравнению с исходным кодом.
Еще один пример, который объяснит вам концепцию getchar и буферизованного stdin:
void main(){
int c;
printf("Enter character");
c = getchar();
putchar();
c = getchar();
putchar();
}
Введите два символа в первом случае. Во второй раз, когда работает getchar, вы вводите любой символ? NO, но все же putchar работает.
В конечном итоге это означает, что есть буфер, и когда вы когда-либо вводите что-то, и нажмите "Enter", это произойдет и оседает в буфере. getchar использует этот буфер как stdin.