2013-08-27 18 views
20

Voglio scrivere un programma C su linux che aggiorna lo schermo continuamente e lo aggiorna in tempo reale (ad esempio, simile al comando top nel terminale). Qualcuno può indicarmi la giusta direzione.Come aggiornare lo schermo continuamente e aggiornarlo in tempo reale

+6

http://en.wikipedia.org/wiki/Ncurses – devnull

+1

Date un'occhiata a [NCURSES] (http://www.tldp.org/HOWTO/NCURSES-Programming- HOWTO /) –

+1

Dai un'occhiata a [ncurses] (http://www.gnu.org/software/ncurses/) –

risposta

27

Per mantenerlo portatile tra i tipi di terminale, è necessario utilizzare una libreria come ncurses. Controlla quel link, è un tutorial esaustivo.

Ecco un programma di base che consente di stampare un numero sempre crescente in alto a sinistra dello schermo:

#include <stdio.h> 
#include <ncurses.h> 

int main (void) 

{ 
     /* compile with gcc -lncurses file.c */ 
     int c = 0; 
     /* Init ncurses mode */ 
     initscr(); 
     /* Hide cursor */ 
     curs_set (0); 
     while (c < 1000) { 
       /* Print at row 0, col 0 */ 
       mvprintw (0, 0, "%d", c++); 
       refresh(); 
       sleep (1); 
     } 
     /* End ncurses mode */ 
     endwin(); 
     return 0; 
} 

Thats come si aggiorna la finestra. Ora, se si desidera visualizzare righe di dati come top, i dati visualizzati devono essere mantenuti in una struttura dati ordinata (a seconda dei dati, forse qualcosa di semplice come un array o una lista collegata). Dovresti ordinare i dati in base a ciò che la tua logica detta e riscrivere alla finestra (come mostrato nell'esempio sopra) dopo un clear() o wclear().

7

Ncurses potrebbe essere la strada da percorrere. Dal momento che hai detto programma, quindi ncurses, c, C++. Guarda tutto. Ma se hai intenzione di fare solo qualcosa di "shell", vai con perl.

Modifica: Per aggiungere al mio punto, ecco alcuni moduli che possono darvi un'idea.

http://metacpan.org/pod/Curses::UI::Dialog::Progress

http://metacpan.org/pod/Smart::Comments

window.clrtobot() 

E per buona misura, un invito a maledizioni per cancellare l'intera finestra.

3

Oltre a utilizzare la libreria ncurses per gestire la schermata, se si desidera aggiornarlo "in modo continuo" e "in tempo reale" probabilmente si vorrà esaminare anche i timer e la gestione dei segnali. timer_create() e timer_settime() possono farti andare un timer, e quindi puoi usare sigaction() per impostare una funzione di gestore per intercettare il segnale SIGALRM e fare il tuo aggiornamento.

EDIT: Ecco alcuni esempi di codice, come richiesto:

#define TIMESTEP 200000000 

timer_t SetTimer(void) { 
    struct itimerspec new_its; 
    struct sigevent sevp; 
    timer_t main_timer; 

    sevp.sigev_notify = SIGEV_SIGNAL; 
    sevp.sigev_signo = SIGALRM; 
    timer_create(CLOCK_REALTIME, &sevp, &main_timer); 

    new_its.it_interval.tv_sec = 0; 
    new_its.it_interval.tv_nsec = TIMESTEP; 
    new_its.it_value.tv_sec = 0; 
    new_its.it_value.tv_nsec = TIMESTEP; 

    timer_settime(main_timer, 0, &new_its, NULL); 
    return main_timer; 
} 

void SetSignals(void) { 
    struct sigaction sa; 

    /* Fill in sigaction struct */ 

    sa.sa_handler = handler; 
    sa.sa_flags = 0; 
    sigemptyset(&sa.sa_mask); 

    /* Set signal handler */ 

    sigaction(SIGALRM, &sa, NULL); 
} 

void handler(int signum) { 
    switch (signum) { 
    case SIGALRM: 
     update_stuff(); /* Do your updating here */ 
     break; 
    } 
} 
+0

Puoi fornire un esempio di questo codice? –

+0

@ sr01853: Certo, ho modificato la risposta per aggiungere un esempio. –

2

Come gli altri hanno detto, probabilmente si vuole guardare la libreria ncurses. Ma se non avete bisogno di formattazione avanzata, forse qualcosa di semplice come questo può essere sufficiente:

#include <stdio.h> 
#include <unistd.h> 

int main(void) { 
    int number = 0; 
    while (1) { 
     ++number; 
     printf("\rThe number is now %d.", number); 
     fflush(stdout); 
     sleep(1); 
    } 
    return 0; 
} 
6

Se hai meno di xterm o VT100 compatibile, è possibile fare uso di console codes, ad esempio:

#include <stdio.h> 
#include <unistd.h> /* for sleep */ 

#define update() printf("\033[H\033[J") 
#define gotoxy(x, y) printf("\033[%d;%dH", x, y) 

int main(void) 
{ 
    update(); 
    puts("Hello"); 
    puts("Line 2"); 
    sleep(2); 
    gotoxy(0, 0); 
    puts("Line 1"); 
    sleep(2); 
    return(0); 
} 

È possibile eseguire quasi tutto con sequenze di escape, ma as pointed out in wikipedia: ncurses ottimizza le modifiche dello schermo, al fine di ridurre la latenza riscontrata durante l'utilizzo di shell remote.

+0

È meglio usare 'fputs (..., stdout)' invece di 'printf (...)'. –

+0

@LS_dev, hai ragione, editato –

+0

Mi riferivo a '# define' ... In' main', 'puts' sarebbe sufficiente. –

5

A seconda della situazione, è possibile utilizzare il comando "guarda" sulla riga di comando per ottenere viste rapide come in alto. Puoi anche guardare più comandi contemporaneamente.

es:

watch 'ls -l <somefile>; ps -fC <someprocess>; ./some_script' 
Problemi correlati