Curses - 对标准输入执行非阻塞检查 - C

发布于 2024-10-07 08:21:49 字数 1185 浏览 4 评论 0原文

我想从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

失去的东西太少 2024-10-14 08:21:49

尝试在 fileno( stdin ) 上使用 select 来告知何时可以从 stdin 读取某些内容。

查看这个链接作为示例。

另请记住,您必须使用准备从 stdin 读取的内容,否则 select 将继续指示准备就绪。

另请注意,这在 Windows 上不起作用。考虑使用 PeekConsoleInput

Try using select on fileno( 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.

贩梦商人 2024-10-14 08:21:49

有几种方法可以解决这个问题。在我看来,以下是更简单的:

  1. 以非阻塞方式读取您的输入。

  2. 使用 I/O 多路复用。在 Unix 中,即 select()poll() 及其同类。

  3. 触发一个线程并让它在读取 stdin 时阻塞。

谷歌搜索最适合你的,有很多有用的信息。

There are several ways around this. Here are, in my opinion, the simpler ones:

  1. Read from your input in a non-blocking manner.

  2. Use I/O multiplexing. In Unix, that is select(), poll() and its cousins.

  3. Fire a thread and have it block on reading stdin.

Google up what suits you best, there's a lot of good information around.

仄言 2024-10-14 08:21:49

您不应该将 fgets() 这样的 stdio 函数与 wgetch() 这样的curses 函数混合在一起。

编写 fgets() 的替代品,在内部调用 wgetch(),累积字符直到输入换行符。

You should not be mixing stdio functions like fgets() with curses functions like wgetch().

Write a replacement for fgets() that calls wgetch() internally, accumulating characters until a newline is entered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文