关闭ncurses窗口后返回正常的终端I / O.

时间:2014-12-11 22:45:57

标签: c unix io ncurses curses

在游戏中,我使用initscr()创建一个ncurses窗口,然后用户玩游戏,当游戏结束时,程序使用endwin()关闭窗口然后打印一些语句并从用户获取输入printf和scanf分别。我的问题是,每当游戏结束时,scanf总是在printf之前执行。所以它等待响应,一旦用户输入响应,它就会打印出scanf语句之前和之后的所有内容。以下是一些示例代码:

...

endwin();
system("clear"); /* Clears terminal window */
printf("New high score!\nPlease enter your first name: ");
scanf("%s",name);

... /* file I/O stuff */

printf("Congratulations, %s!",name);

如您所见,printf语句位于scanf语句之前,但由于某种原因,scanf首先执行。我在没有ncurses窗口的情况下测试了代码,得到了理想的结果。有谁知道造成这种情况的原因是什么?

2 个答案:

答案 0 :(得分:0)

  

与诅咒没什么关系。

这句话显然是错误的,因为使用 curses 会产生影响,正如问题所述:

  

如您所见,printf语句位于scanf语句之前,但是   由于某种原因,scanf首先执行。我没有测试代码   ncurses窗口,我得到了理想的结果。有谁知道是什么   引起这个?

虽然fflush(stdout)给出了所需的结果是正确的,但这并没有回答这个问题。

导致这种情况的原因可能是实现定义的标准I / O特性,在请求输入时刷新行缓冲 stdout(有时在man setbuf中记录),和 curses stdout设置为完全缓冲,从而禁用自动刷新。

答案 1 :(得分:0)

您可以在手册页中阅读相关内容,并在其中讨论NCURSES_NO_SETBUF

  • 为了获得良好的性能,大多数curses实现将输出缓冲从面向行的更改为面向缓冲的(以便库可以进行更大,更高效的写入)
  • 因为这意味着对标准输出的所有写入将被缓冲,这是一个麻烦。 ncurses提供了一个覆盖缓冲的选项(环境变量)。
  • 通过完全取消stdout缓冲以解决信号处理问题,
  • 2012中发生了变化。
  • 然而,“消除”缓冲意味着ncurses使用自己的缓冲区。它会在endwin中刷新 ,但在切换到curses模式时不会刷新stdout
  • 少数 应用程序需要修改以刷新标准输出。

2012年对ncurses的更改是August 2015中ncurses6版本的一部分。 OP的问题是ncurses5.9(或更早),因为它描述了缓冲标准输出的应用程序。