2009-09-02 17 views
5

Le mie scuse per un titolo non accurato, ma non sono sicuro di ciò che si chiama esattamente.Stampa su console senza flooding in C++

Come si stampa sulla console una singola riga di aggiornamento?

Ad esempio, se volessi stampare uno stato di completamento percentuale in ogni ciclo ma non inondare la console con flussi di testo, come potrei realizzare questo? (Come si chiama? - per future ricerche su Google)

Grazie!

risposta

11

Non v'è alcun modo portabile per pulire lo schermo anche se c'è un modo semplice per tornare all'inizio della linea di utilizzando \r poi sovrascrivere quello che abbiamo scritto prima. Sto usando Sleep da Windows API:

#include <iostream> 
#include <windows.h> 
using namespace std; 

int main() 
{ 
for(int i = 1; i <= 10; i++) 
{ 
    std::cout << i*10 << '%'; 
    std::cout.flush(); // see wintermute's comment 
    Sleep(1000); 
    std::cout << '\r'; 
} 
} 
+0

Per ulteriore illuminazione, '\ r' restituisce un ritorno a capo. –

+6

Si potrebbe voler chiamare 'std :: cout.flush()' prima di 'Sleep()' dato che 'std :: cout' è un flusso bufferizzato e quindi il contenuto potrebbe non essere visualizzato quando previsto. –

+1

Come dice Dan, '\ r' è un ritorno a capo, che non * cancella * la riga, sposta semplicemente il cursore indietro all'inizio della riga. –

2

La soluzione di base è quella:

loop: 
    backspace (over written text) 
    write (without newline) 
    flush 
    wait and get updates 

In alternativa, si potrebbe provare una soluzione che utilizza la libreria curses - anche se non sono sicuro se questo è proprio quello che sei dopo. Maledizioni fornisce la grafica di base ascii per GUI basate su testo (a volte chiamato TUI).

+0

Maledizioni è l'unico modo per farlo abilmente. Si noti che la console è parte del database di curses. –

3

Le maledizioni sono l'unico modo per farlo portabilmente.

Date un'occhiata a questo: http://code.google.com/p/tinycurses/wiki/basic1

+2

Non direi il "solo" modo. Se il terminale è compatibile ANSI, è possibile emettere "\ r" o "\ 015". Se è compatibile con VT-100, puoi anche inviare '\ 033 [5n' al TTY e la risposta sarà lungo le linee di '\ 033 [5; 5R' e quindi puoi inviare '\ 033 [5; 0H 'per andare all'inizio della riga 5. Questo è tutto ciò che ncurses fa comunque. – greyfade

+0

L'unico modo ** portatile **. Perché le cure estrapolano il terminale in modo che non sia necessario conoscere un VT-100 compatibile o altro. Puoi fare ciò che descrivi in ​​quasi tutti i terminali che devi solo scavare nella documentazione e comprenderlo. Ecco perché lo abbiamo maledetto ** ABSTRACTS ** il terminale in modo da non aver bisogno di sapere, quindi è l'unico ** PORTATILE ** modo. OK ci sono altre librerie (come ncurses). O si è appena ricordato che ncurses è solo una maledizione ma una nuova versione :-) –

0

Quanto velocemente sono i cicli? Sono nel millisecondo o secondi. Se i cicli sono brevi, si consiglia di aggiornare lo schermo dopo un secondo in modalità elpata.

Per esempio

include <time.h> /* if memory serves me correctly */ 
    int currentTime = time(0); 
    for (int i = 0; i < 100; i++) 
    { 
    /* do work here and save the percentage completed */ 
    lastTime = time(0); 
    if ((lastTime-currentTime) >= 1) 
    { 
     /* output percentage completed (using AraK information) */ 
     currentTime = lastTime; 
    } 
    } 

Questo sarà solo aggiornare lo schermo ogni secondo e salvare il tempo a scrivere sullo schermo come si consuma il tempo per ridisegnare lo schermo (che è possibile utilizzare per l'elaborazione). Inoltre, se i tuoi aggiornamenti vanno così veloci, questo ti permette di vedere la percentuale se i tuoi cicli sono piuttosto brevi, dato che potresti ridisegnare lo schermo tutto il tempo.

Nota: aggiornato in base ai commenti.

+0

Deve essere il tempo (0). time() prende l'indirizzo di un time_t, aggiornando il time_t referenziato se fornito. –

+2

Oppure è possibile aggiornarlo solo quando la percentuale aumenta effettivamente, non è necessario aggiornarlo se verrà visualizzata la stessa cosa e con il numero di chiamate di disegno che non supererà 101 (supponendo una visualizzazione 0% -> 100%) , il disegno non avrà molto impatto sulle prestazioni –

+0

Grazie per l'input. È passato un po 'di tempo da quando ho usato la funzione del tempo. – Glenn

0

Dipende dalla piattaforma che si sta utilizzando. Non sono sicuro di come lo fai su Linux, ma su Windows puoi usare WriteConsole o SetConsoleCursorPosition per farlo.

Non credo che un modo completamente portatile per farlo esista diverso dall'output di una tonnellata di backspaces come già menzionato. Il metodo backspace può causare un grande sfarfallio che potrebbe non essere accettabile nell'applicazione ... le funzioni Win32 non provocano lo sfarfallio. Non sono sicuro della libreria di curses.