2010-12-11 6 views
2

Je souhaite traiter un tube/terminal à partir de stdin, mais en même temps, je souhaite que mes autres opérations continuent à être traitées, telles que le menu UP/DOWN .Curses - Effectuer un contrôle non bloquant sur stdin - C

fgets finit de traiter les lignes canalisées et les écrans deviennent rendus, cependant, wgetch ne répond plus, donc je ne peux rien faire à l'intérieur du commutateur. Pour fermer l'application, je dois 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

Cela semble correct. Pouvez-vous afficher la ligne de commande que vous utilisez pour appeler le programme? –

+0

@Luke Dunstan: 'echo" FOO "| ./a.out' ou juste './a.out' de toute façon cela ne fonctionne pas/répond correctement. – MikeCooper

Répondre

1

Essayez d'utiliser select sur fileno(stdin) de dire quand quelque chose est prêt à être lu à partir de stdin.

Consultez le lien this pour un exemple. De plus, gardez à l'esprit que vous devez consommer ce qui est prêt à lire à partir de stdin ou select continuera à indiquer la disponibilité.

Notez également que cela ne fonctionnera pas sur Windows. Regardez dans l'utilisation PeekConsoleInput.

+0

pourriez-vous élaborer un peu plus à ce sujet? Merci – MikeCooper

1

Il y a plusieurs façons de contourner cela. Voici, à mon avis, les plus simples:

  1. Lire à partir de votre entrée d'une manière non-bloquante.

  2. Utiliser le multiplexage d'E/S. Dans Unix, c'est select(), poll() et ses cousins.

  3. Lancez un thread et bloquez-le en lisant stdin.

Google jusqu'à ce qui vous convient le mieux, il y a beaucoup de bonnes informations.

1

Vous ne devez pas mélanger des fonctions stdio telles que fgets() avec des fonctions curses telles que wgetch().

Ecrivez un remplacement pour fgets() qui appelle wgetch() en interne, en accumulant des caractères jusqu'à ce qu'un nouveau saut soit entré.