2010-12-11 49 views
2

我想從stdin處理管道/終端,但是,同時我希望我的其他操作保持繼續處理,例如上/下菜單Curses - 對stdin執行非阻塞檢查 - C

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(); 
} 
+0

看起來沒問題。你能顯示你用來調用程序的命令行嗎? – 2010-12-12 01:55:31

+0

@Luke Dunstan:'echo「FOO」| ./a.out'或者只是'.a.out',它不能正常工作/響應。 – MikeCooper 2010-12-12 02:46:14

回答

1

嘗試使用selectfileno(stdin)告訴當事情是準備從標準輸入讀取。

查看this鏈接爲例。

還請記住,您必須使用準備從stdin讀取的內容,否則select將繼續指示準備就緒。

另請注意,這不適用於Windows。看看使用PeekConsoleInput

+0

你能詳細解釋一下嗎?謝謝 – MikeCooper 2010-12-12 01:09:04

1

有幾種解決方法。在我看來,這是更簡單的:

  1. 以非阻塞方式讀取您的輸入。

  2. 使用I/O多路複用。在Unix中,這是select(),poll()及其堂兄弟。

  3. 觸發一個線程並在閱讀stdin時阻止它。

谷歌最適合你的是什麼,有很多好的信息。

1

你不應該混合像fgets() stdio功能與詛咒功能,如wgetch()

寫一個fgets()的替代品,它在內部調用wgetch(),累積字符,直到輸入換行符。