2

我在与 ncurses 库混合freopen时遇到问题。stdin

我所做的是将标准输入重新打开到一个文件,通过 flex+bison 解析它,然后我应该将它恢复回来并启动 ncurses。

交换代码如下:

void switchStdin(const char *newStream) {
  fflush(stdin);
  fgetpos(stdin, &pos);
  fd = dup(fileno(stdin));
  freopen(newStream, "r", stdin);
}

void revertStdin() {
  fflush(stdin);
  dup2(fd, fileno(stdin));
  close(fd);
  clearerr(stdin);
  fsetpos(stdin, &pos);
}

在我的词法分析器中,这就是我所做的:

void parse() {
  Utils::switchStdin("./filename.ext");
  yyparse();
  Utils::revertStdin();
}

在主文件中我只是做类似的事情

parse();

initscr();
keypad(stdscr, TRUE);
noecho();
cbreak();
...

现在,如果我不评论revertStdin它只是在启动时停止,如果我评论它,解析确实有效,但 ncurses gui 没有响应并且不时闪烁。

由于这两个部分在独立使用时都可以工作,我猜想以我错过的顺序方式混合它们有一些警告。有人有线索吗?

4

1 回答 1

0

问题不止一个,但重要的是revertStdin打开流没有成功:

  • switchStdin不必要地调用 non-portable fflush(stdin)
  • 它保存 in 的文件描述符和stdininfd的文件位置pos
  • 不需要文件位置(因为终端不这样做
  • revertStdin不必要地调用 non-portable fflush(stdin)
  • 试图stdin覆盖使用已保存的文件描述符fd。那是行不通的。
  • 在某些系统上,您无法为stdin;分配新值 碰巧GNU C 库允许这样做。如果您使用的是 Linux,则可以使用来解决问题fdopen,例如,
    标准输入 = fdopen(fd, "r");
  • 如果不是(更便携),您将使用newterm而不是initscr. 与 不同initscrnewterm允许您指定输入和输出的流。在这种情况下,您仍然会使用fdopen,但不会尝试分配给stdin。使用您自己的变量并将其传递newterm.
于 2017-02-19T21:39:58.213 回答