2011-01-23 14 views
8

Sto imparando a programmare in C e voglio essere in grado di digitare caratteri nel terminale mentre il mio codice è in esecuzione senza premere restituire. Il mio programma funziona, tuttavia quando chiamo initscr(), lo schermo viene cancellato, anche dopo aver chiamato filter(). La documentazione per filter suggerisce che dovrebbe disabilitare la cancellazione, tuttavia non è questo il mio caso.Come si usa getch dalle maledizioni senza cancellare lo schermo?

#include <stdio.h> 
#include <curses.h> 
#include <term.h> 

int main(void) { 

    int ch; 

    filter(); 
    initscr(); 
    cbreak(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    while((ch = getch()) != EOF); 

    endwin(); 

    return 0; 
} 

Perché il codice sopra riportato cancella lo schermo e cosa si può fare per risolverlo?

Sto usando Debian Lenny (stabile) e gnome-terminal se questo aiuta.

+0

Per PDCurses è possibile impostare l'PDC_PRESERVE_SCREEN variabili d'ambiente o PDC_RESTORE_SCREEN qualsiasi valore: dal file STORIA: – Brandin

+0

PDC_PRESERVE_SCREEN Se questa variabile d'ambiente è impostato, PDCurses non cancellerà lo schermo sul bianco predefinito all'avvio. Ciò consente di sovrapporre a una finestra nella parte superiore dello sfondo dello schermo esistente. PDC_RESTORE_SCREEN Se questa variabile di ambiente è impostata, PDCurses prenderà una copia del contenuto dello schermo nello al momento dell'avvio di PDCurses; initscr(), e quando viene chiamato endwin(), lo schermo verrà ripristinato. – Brandin

risposta

2

Utilizzare newterm() invece di initscr(), si dovrebbe andare bene allora. E non dimenticare di delscreen() se segui questo consiglio.

+0

Ciao, grazie per la risposta, ho provato quello che hai detto e la funzionalità è la stessa - lo schermo è stato nuovamente cancellato. Al posto di 'initscr()' ho 'FILE * fild_id = fopen ("/dev/tty "," r + "); SCREEN * termref = newterm (NULL, file_id, file_id); 'e invece di' endwin() 'Ho' delscreen (termref) '. –

+0

Strano ma non cancella il mio schermo quando lo uso al posto di 'initscr()'. Però lo chiamo come 'newterm (NULL, stdin, stdout)'. –

+3

L'unico motivo per cui non si cancella lo schermo, Mike, è che hai invertito gli argomenti in newterm(). Prende stdout, stdin, non stdin, stdout. Scommetto che dopo l'esecuzione del programma di test, il tuo input è incasinato? Non riecheggia, forse? Se si utilizza l'ordine di argomento corretto per newterm(), in effetti cancella lo schermo. La tua risposta è semplicemente sbagliata. –

4

Estendendo la risposta di mike.dld, questo funziona per me su MacOS X 10.6.6 (GCC 4.5.2) con la libreria di curses di sistema - senza cancellare lo schermo. Ho aggiunto la possibilità di registrare i caratteri digitati (registrati in un file "x") e la possibilità di digitare CONTROL-D e interrompere il programma anziché forzare l'utente a interrompere.

#include <stdio.h> 
#include <curses.h> 
#include <term.h> 

#define CONTROL(x) ((x) & 0x1F) 

int main(void) 
{ 
    FILE *fp = fopen("x", "w"); 
    if (fp == 0) 
     return(-1); 
    SCREEN *s = newterm(NULL, stdin, stdout); 
    if (s == 0) 
     return(-1); 
    cbreak(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    int ch; 
    while ((ch = getch()) != EOF && ch != CONTROL('d')) 
     fprintf(fp, "%d\n", ch); 

    endwin(); 

    return 0; 
} 
+0

Grazie ragazzi per aver risposto, questo ha funzionato perfettamente –

+0

Questo mi libera lo schermo (quindi non funziona). – nh2

+0

@ nh2: potrebbe dipendere dal tipo di terminale e dalla voce curses che stai utilizzando. –

0

Fondamentalmente, curses è progettato per rilevare lo schermo (o finestra, nel caso di un terminale con finestra). Non puoi mescolare le maledizioni con lo stdio, e non puoi usare le curses per inserire o emettere qualcosa senza occupare il resto dello schermo. Esistono soluzioni temporanee parziali, ma non riuscirai mai a farlo funzionare nel modo in cui sembra che tu voglia. Scusate.

Suggerirei di riscrivere il programma per usare curses in tutto o di esaminare alternative come readline.

+0

readline utilizza internamente ncurses. –

+1

readline utilizza solo l'interfaccia termcap –

1

si dovrebbe vedere lo schermo eliminato in un'applicazione maledizioni per uno di questi motivi:

  • il programma chiama initscr (che cancella lo schermo) o newterm senza prima chiamare filter, o
  • l'inizializzazione del terminale cancella lo schermo (o lo fa sembrare chiaro, passando allo schermo alternativo).

In quest'ultimo caso, si può sopprimere la funzione di schermo si alternano in ncurses reimpostando le enter_ca_mode e exit_ca_mode puntatori NULL as done in dialog. Meglio ancora, scegli una descrizione del terminale che faccia ciò che vuoi.

Ulteriori approfondimenti: