2017-01-09 62 views
2

我创建了一个使用AppKit读取系统范围击键的ncurses程序。要在运行程序时清除在命令行上累积的文本的墙,我在退出程序之前执行这一行代码。C禁用命令行输入

while((c = getch()) != '\n' && c != EOF) {} 

我的问题是如果有一个更有效的方法来解决这个问题。例如,在程序执行时禁用命令行输入。

编辑:

我跑了一些测试,我的问题似乎根植于usleep而不是ncurses的或AppKit的。这里有一个例子:

#include <unistd.h> 

int main() { 
    usleep(5000000); 
    return 0; 
} 
+0

当程序运行时,终端中的输入应该在程序退出时被丢弃。应该没有必要明确地做到这一点。 –

+0

对我来说,这是当我退出(0)程序的命令行: 的bash-4.4 $ ddddddaaaaaaaaaaawwwwwwwwwwdddddddddddddddddddddddddddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaax –

+3

听起来像一个XY问题。目前还不清楚你想完成什么。提供一个[mcve]的细节。 – Olaf

回答

3

exit()之前尝试tcflush(STDIN_FILENO, TCIFLUSH)


根据tcflush(3)

int tcflush(int fd, int queue_selector);

tcflush()写入到对象丢弃数据通过fd称为但不传送或接收的数据,但不能读取,取决于queue_selector值:

TCIFLUSH :刷新收到的数据但不是r元首。
TCOFLUSH :刷新已写入但未传输的数据。
TCIOFLUSH:刷新收到但未读取的数据,以及写入但未发送的数据。

+0

谢谢,它的作品,但我不知道这个功能可以完全禁用。 –

+0

我不认为这是可能的。您的应用程序可以轻松忽略输入,因此终端驱动程序无需提供此类功能,因为它不能真正阻止用户从键盘输入。 – pynexj

2

诅咒提供的功能对于这一点,叫flushinp

flushinp常规扔掉已经 被用户键入,并且还没有被 程序读取任何预输入。

您的两个节目片段不显示这一点,但ncurses的手册页对initialization节建议您关闭回声(由诅咒)开始:

initscr(); cbreak(); noecho(); 

无论你做或没有,诅咒实际上将终端置于原始模式并选择是否在程序以curses模式运行时回显键入的字符。

第一个片段,使用getch是一个curses函数。 ncurses尝试将所有输入字符读入自己的缓冲区,并按照程序需要的速度处理它们。 flushinp调用告诉它放弃缓冲的输入。顺便说一句,您的代码应该使用ERR作为检查而不是EOF,尽管对于curses的大多数实现它们是相同的数值。

当程序停止curses模式(使用endwin)时,它将终端恢复到最初的模式,即回显缓冲输入。

代码的其它片段不是一个诅咒应用。终端停留在烹饪模式(回声,缓冲),并在终端驱动程序中累积,未被您的程序读取。在退出程序时,下一个程序(或您的shell)有机会阅读该程序。

至于建议(而隐含的),如果你的程序是不是在诅咒模式下运行它退出时,您可以使用POSIX termios calltcflush丢弃输入端子,这是的ncurses做什么(见source)未决。