2009-09-02 5 views
5

Mes excuses pour un titre inexact, mais je ne suis pas sûr de ce que cela s'appelle exactement. Comment peut-on imprimer sur la console une seule ligne de mise à jour? Par exemple, si je voulais imprimer un pourcentage d'avancement à chaque cycle sans inonder la console de vapeur, comment pourrais-je y parvenir? (Comment s'appelle-t-il? - pour un futur googling)Imprimer à la console sans inondation en C++

Merci!

Répondre

11

Il n'y a aucun moyen portable pour nettoyer l'écran mais il existe un moyen simple de revenir au début de la ligne utilisant \r alors ce que nous écraser écrit avant. J'utilise Sleep de 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

Pour un éclairage supplémentaire, '\ r' produit un retour chariot. –

+6

Vous pouvez appeler 'std :: cout.flush()' avant 'Sleep()' car 'std :: cout' est un flux bufferisé et donc son contenu risque de ne pas s'afficher quand vous le souhaitez. –

+1

Comme le dit Dan, '\ r' est un retour chariot, qui ne * supprime * pas la ligne, il ramène simplement le curseur au début de la ligne. –

2

La solution de base est de:

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

Alternativement, vous pouvez essayer une solution en utilisant la bibliothèque curses - bien que je ne suis pas sûr que ce soit tout à fait ce que vous êtes après. Curses fournit vos graphiques ascii de base pour les GUI basées sur du texte (parfois appelé un TUI).

+0

Les malédictions sont la seule façon de faire ce port habilement. Notez qu'il suppose que votre console fait partie de la base de données curses. –

3

Les malédictions ne sont qu'un moyen de le faire de façon portative.

Jetez un oeil à ceci: http://code.google.com/p/tinycurses/wiki/basic1

+2

Je ne dirais pas le "seul" moyen. Si le terminal est compatible ANSI, vous pouvez sortir "\ r" ou "\ 015". Si elle est compatible VT-100, vous pouvez également sortir '\ 033 [5n' vers le TTY et la réponse sera sur les lignes de '\ 033 [5; 5R' et vous pourrez alors envoyer '\ 033 [5; 0H «Aller au début de la ligne 5. C'est tout ce que ncurses fait de toute façon. – greyfade

+0

La seule façon ** portable **. Parce que les traitements résume le terminal de sorte que vous n'avez pas besoin de connaître son un VT-100 compatible ou autre chose. Vous pouvez faire ce que vous décrivez dans n'importe quel terminal que vous avez juste à creuser dans la documentation et à le comprendre. C'est pourquoi nous l'avons maudit ** ABSTRACTS ** le terminal de sorte que vous n'avez pas besoin de savoir, est donc la seule façon ** PORTABLE **. OK, il existe d'autres bibliothèques (comme ncurses). O oui je me souviens juste que ncurses est juste des malédictions mais une nouvelle version :-) –

0

Comment sont rapides vos cycles? Sont-ils dans la milliseconde, ou secondes. Si vos cycles sont courts, vous voudrez peut-être seulement mettre à jour l'écran après une seconde.

Par exemple

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; 
    } 
    } 

Cela ne met à jour l'écran chaque seconde et enregistrer le temps à écrire à l'écran comme il consomme le temps de redessiner l'écran (que vous pouvez utiliser pour le traitement). En outre, si vos mises à jour vont si vite, cela permet à l'utilisateur de voir le pourcentage si vos cycles sont assez courts, car vous pourriez redessiner l'écran tout le temps.

Note: Mis à jour en fonction des commentaires.

+0

A besoin d'être le temps (0). time() prend l'adresse d'un time_t, mettant à jour le time_t référencé si donné. –

+2

Ou vous pouvez juste le mettre à jour quand le pourcentage augmente réellement, il n'y a aucun point le mettre à jour si la même chose va être affichée, et avec le nombre d'appels de dessin ne dépassant pas 101 (en supposant un affichage de 0% -> 100%) , le dessin ne va pas avoir beaucoup d'impact sur la performance –

+0

Merci pour l'entrée. Cela fait un moment que j'ai utilisé la fonction de temps. – Glenn

0

Cela dépend de la plate-forme que vous utilisez. Je ne suis pas sûr comment vous faites cela sur Linux, mais sur Windows, vous pouvez soit utiliser WriteConsole ou SetConsoleCursorPosition pour ce faire.

Je ne crois pas qu'une manière complètement portable de faire cela existe autre que de sortir une tonne de backspaces comme déjà mentionné. La méthode de retour arrière peut causer beaucoup de scintillement qui peut être inacceptable dans votre application ... les fonctions Win32 ne provoquent pas de scintillement. Pas sûr de la bibliothèque de curses.

Questions connexes