Использование getchar () после read () - PullRequest
3 голосов
/ 03 октября 2009

C для захвата клавиатуры. Следующий код находит, когда нажата клавиша со стрелкой / esc. В то же время я хочу прочитать целые слова, которые вводит пользователь, и они также должны быть показаны на stdout .

char pp = 0;
char p = 0;
while( (i = read(0, &c, 1)) == 1) {
if (pp == 033 && p == 0133 && (c &= 255) == 0102) /* DOWN */ break;
if (c == 0177) /* ASCII DELETE */ break;
printf( "%o, %o, %o\t%s\n\r", pp, p, c, &c);
pp = p;
p = c; 
}
...
...
getchar(); //I want to capture here what was entered before
           //  **return key** was pressed.

Но этот код не работает, если я удаляю '\ n'. Я хочу, чтобы стандартный вывод вел себя как обычный шелл.

Ответы [ 3 ]

3 голосов
/ 03 октября 2009

printf(3) проходит через буферизованное средство ввода-вывода <stdio.h>, которое включает в себя fputs(3) и fputc(3). Вы наблюдаете нормальное поведение буферизации линии. Вы можете победить эту буферизацию, как отмечено с помощью setbuf(3), однако, так как вы не хотите ее в первую очередь, и вы уже используете прямой вызов ядра (read(2)) для чтения, почему бы не немного изменить свою логику напрямую вызвать ядро ​​с write(2)?

char buffer[100];

int n;

n = snprintf(buffer, sizeof buffer, "format string...", args...);
write(1, buffer, n)

И если вы хотите, вы можете определить свой собственный directPrintf, чтобы сделать это проще:

#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>

int directPrintf(const char *format, ...)
{
va_list ap;
char buffer[200];

    va_start(ap, format);
    int n = vsnprintf(buffer, sizeof buffer, format, ap);
    va_end(ap);
    return write(1, buffer, n);
}
0 голосов
/ 03 октября 2009

вставить

setbuf( stdout, NULL);

где-то в начале и удалите \ n.

0 голосов
/ 03 октября 2009

getchar(), вероятно, реализован в терминах read(), который читает намного больше, чем 1 байт (обычно целый PIPE_BUF или 4096 байт). Затем он поддерживает частный курсор для этого буфера, извлекая байты по мере необходимости.

Это сделано потому, что read() имеет нетривиальные издержки, связанные с просто вызовом it.

printf() и fwrite() (и т. Д.) Также буферизуются по той же причине (write() имеет нетривиальные издержки). Вызов fflush(stdout) преобразуется в write() вызов того, что было буферизовано, но не отправлено на базовый порт ввода-вывода.

Наконец, у вас есть \n\r задом наперед; это почти наверняка должно быть \r\n

...