NCurses перенаправление стандартного ввода - PullRequest
0 голосов
/ 21 апреля 2020

Я не понимаю, почему функция getch () все время возвращает ERR, если у меня настроено приложение (обнажено до костей):

static char data[DATA_SIZE]; // Very big - covers all input for sure

int main(int argn, char ** argv)
{

  // Slurp the file in
  int length = read(0, &data[0], DATA_SIZE);
  if (length == 0)
  {
    fprintf(stderr, "Nothing to read\n");
    return 0;
  }

  initscr();
  cbreak();
  refresh();
  WINDOW * woutput = newwin(LINES - 1, COLS, 0, 0);
  WINDOW * winput  = newwin(1, COLS, LINES - 1, 0);
  wattron(winput, A_REVERSE);
  keypad(winput, TRUE);

   //print the data buffer into a window

  int c;
  while ((c = wgetch(winput)) != 'q')
  {
  }
}

Я запускаю приложение в таким образом:

./application < path/to/file

Но результат wgetch всегда 'ERR'.

1 Ответ

0 голосов
/ 21 апреля 2020

Поскольку вы прочитали stdin до конца файла, wgetch сразу же получит конец файла, когда попытается прочитать. Но в любом случае вы не хотите, чтобы ncurses использовал перенаправленный stdin; Вы хотите, чтобы он использовал терминал.

Один из способов сделать это - просто повторно открыть stdin в качестве терминала перед вызовом initscr:

#include <stdio.h>
#include <ncurses.h>

int main(int argn, char ** argv)
{
  // Just discard all of stdin for a minimal example
  while (fgetc(stdin) != EOF) { }

  // See note
  if (!freopen("/dev/tty", "r", stdin)) {
    perror("/dev/tty");
    exit(1);
  }
  initscr();

  cbreak();
  refresh();
  WINDOW * woutput = newwin(LINES - 1, COLS, 0, 0);
  WINDOW * winput  = newwin(1, COLS, LINES - 1, 0);
  wattron(winput, A_REVERSE);
  keypad(winput, TRUE);

  // Echo input into full screen
  int c;
  while ((c = wgetch(winput)) != 'q') { wechochar(woutput, c); }
  endwin();
  return 0;
}

Если вы обнаружите freopen трудно следовать, вы можете заменить его и следующий вызов initscr на

FILE* tty = fopen("/dev/tty", "r");
if (!tty) { perror("/dev/tty"); exit(1); }
if (!newterm(NULL, stdout, tty) {
  fprintf(stderr, "%s\n", "Unable to initialise ncurses");
  exit(1);
}

Примечание:

В приведенном выше коде я просто использовал /dev/tty в качестве имени консоль, которая, вероятно, будет работать в любой умеренно-совместимой системе. Тем не менее, Posix также предоставляет интерфейс, который позволяет вам найти путь к текущему «управляющему терминалу», и, что важно, позволяет узнать, не существует ли его для вашего процесса. См. man ctermid для получения подробной информации и примера использования.

...