Curses - 对标准输入执行非阻塞检查 - C
我想从 stdin
处理管道/终端,但同时,我希望其他操作继续处理,例如向上/向下菜单。
fgets
完成处理管道传输的行并且屏幕得到渲染,但是,wgetch
变得无响应,因此我无法在交换机内执行任何操作。要关闭应用程序,我必须CTRL+c。
#include <curses.h>
#include <menu.h>
char *choices[] = { "Choice 1", "Exit" };
int main()
{
ITEM **my_items, *cur_item;
MENU *my_menu;
int i, c;
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
FILE *fp = stdin;
char line [ 256 ];
while ( fgets ( line, sizeof line, fp) != NULL ) {
printw ( "%s", line);
}
my_items = (ITEM **)calloc(2 + 1, sizeof(ITEM *));
for(i = 0; i < 2; ++i)
my_items[i] = new_item(choices[i], choices[i]);
my_items[2] = (ITEM *)NULL;
my_menu = new_menu((ITEM **)my_items);
mvprintw(LINES - 2, 0, "F1 to Exit");
post_menu(my_menu);
refresh();
timeout(0);
while((c = wgetch(stdscr)) != KEY_F(1))
{ switch(c)
{ case KEY_DOWN:
menu_driver(my_menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(my_menu, REQ_UP_ITEM);
break;
}
}
endwin();
}
I want to process a pipe/terminal from stdin
, however, at the same time, I want my other operations keep continue processing, such as the UP/DOWN menu.
fgets
finishes to process the lines piped and screens gets render, however, wgetch
becomes unresponsive, so I can't do anything inside the switch. To close the application I have to CTRL+c.
#include <curses.h>
#include <menu.h>
char *choices[] = { "Choice 1", "Exit" };
int main()
{
ITEM **my_items, *cur_item;
MENU *my_menu;
int i, c;
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
FILE *fp = stdin;
char line [ 256 ];
while ( fgets ( line, sizeof line, fp) != NULL ) {
printw ( "%s", line);
}
my_items = (ITEM **)calloc(2 + 1, sizeof(ITEM *));
for(i = 0; i < 2; ++i)
my_items[i] = new_item(choices[i], choices[i]);
my_items[2] = (ITEM *)NULL;
my_menu = new_menu((ITEM **)my_items);
mvprintw(LINES - 2, 0, "F1 to Exit");
post_menu(my_menu);
refresh();
timeout(0);
while((c = wgetch(stdscr)) != KEY_F(1))
{ switch(c)
{ case KEY_DOWN:
menu_driver(my_menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(my_menu, REQ_UP_ITEM);
break;
}
}
endwin();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试在
fileno( stdin )
上使用select
来告知何时可以从 stdin 读取某些内容。查看这个链接作为示例。
另请记住,您必须使用准备从 stdin 读取的内容,否则 select 将继续指示准备就绪。
另请注意,这在 Windows 上不起作用。考虑使用
PeekConsoleInput
。Try using
select
onfileno( stdin )
to tell when something is ready to be read from stdin.Check out this link for an example.
Also keep in mind that you have to consume what's ready to read from stdin or select will continue to indicate readiness.
Also note that this will not work on Windows. Look into using
PeekConsoleInput
.有几种方法可以解决这个问题。在我看来,以下是更简单的:
以非阻塞方式读取您的输入。
使用 I/O 多路复用。在 Unix 中,即
select()
、poll()
及其同类。触发一个线程并让它在读取 stdin 时阻塞。
谷歌搜索最适合你的,有很多有用的信息。
There are several ways around this. Here are, in my opinion, the simpler ones:
Read from your input in a non-blocking manner.
Use I/O multiplexing. In Unix, that is
select()
,poll()
and its cousins.Fire a thread and have it block on reading stdin.
Google up what suits you best, there's a lot of good information around.
您不应该将
fgets()
这样的 stdio 函数与wgetch()
这样的curses 函数混合在一起。编写
fgets()
的替代品,在内部调用wgetch()
,累积字符直到输入换行符。You should not be mixing stdio functions like
fgets()
with curses functions likewgetch()
.Write a replacement for
fgets()
that callswgetch()
internally, accumulating characters until a newline is entered.