Мой код C:
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
Почему эта программа так реагирует на ввод hello
?
hello
hello
а не нравится:
hheelloo
Мой код C:
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
Почему эта программа так реагирует на ввод hello
?
hello
hello
а не нравится:
hheelloo
Ваш ввод hello
, а не h
e
l
l
o
верно?
Таким образом, введенные вами данные буферизуются до тех пор, пока вы не нажмете enter.
Когда вы печатаете, консоль захватывает вывод с клавиатуры и возвращает его вам.
getchar()
работает с входным потоком, для которого обычно включен параметр «Канонический ввод». Такая конфигурация сокращает время, затрачиваемое ЦП на опрос ввода для схемы буферизации, в которой ввод буферизуется, до тех пор, пока не произойдут определенные события, сигнализирующие о расширении буфера. Нажатие клавиши ввода (и нажатие кнопки D) приводит к очистке этого буфера.
#include <unistd.h>
int main(void){
int c;
static struct termios oldt;
static struct termios newt;
/* Fetch the old io attributes */
tcgetattr( STDIN_FILENO, &oldt);
/* copy the attributes (to permit restoration) */
newt = oldt;
/* Toggle canonical mode */
newt.c_lflag &= ~(ICANON);
/* apply the new attributes with canonical mode off */
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
/* echo output */
while((c=getchar()) != EOF) {
putchar(c);
fflush(STDOUT_FILENO);
}
/* restore the old io attributes */
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
return 0;
}
Ваш терминал, вероятно, записывает ваш ввод в стандартный ввод только тогда, когда вы нажимаете ввод. Попробуйте напечатать что-нибудь, вернуться назад и написать что-нибудь еще; если вы не видите изначально набранных символов, это означает, что ваш терминал ждал, пока вы составите строку, прежде чем отправлять данные в программу.
Если вам нужен необработанный доступ к терминалу (например, реагировать на нажатие и нажатие клавиши), вам следует попробовать какую-нибудь терминальную библиотеку, например ncurses.
Стандартные потоки ввода/вывода могут быть буферизованы, что означает, что ваш ввод не может быть отображен на экране до тех пор, пока не встретится символ пробела (например).
Потому что по умолчанию для stdin
, когда он относится к клавиатуре, используется буферизация строк.
Это означает, что вы можете видеть только полные строки, а не отдельные символы.
Представьте, что вы спрашиваете своего друга, какой у него номер телефона... но он должен записать его на листе бумаги. Вы не получаете цифру за цифрой, когда он их пишет: вы получаете все числа, когда он дает вам листок бумаги :)
getchar считывает ввод из входного потока, который доступен только после нажатия клавиши ENTER. до тех пор вы видите только эхо-результат с консоли. Чтобы добиться желаемого результата, вы можете использовать что-то вроде этого
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
int getCHAR( ) {
struct termios oldt,
newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
putchar(ch);
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
void main() {
int c;
c = getCHAR();
while (c != 'b') {
putchar(c);
c = getCHAR();
}
}