2009-09-02 16 views
5

Przepraszam za niedokładny tytuł, ale nie jestem pewien, co to się nazywa.Drukuj na konsolę bez zalewania w C++

Jak wydrukować na konsoli pojedynczą, aktualizującą linię?

Na przykład, jeśli chciałbym wydrukować procentowy status ukończenia w każdym cyklu, ale nie zalać konsoli tekstami, jak miałbym to zrobić? (Co to się nazywa? - w przyszłości Googling)

Dziękujemy!

Odpowiedz

11

Nie ma przenośny sposób do czyszczenia ekranu choć nie jest to prosty sposób, aby powrócić do początku wiersza wykorzystaniem \r następnie nadpisanie co pisaliśmy wcześniej. Używam Sleep z 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

W celu dodatkowego oświetlenia, "\ r" wyświetla powrót karetki. –

+6

Możesz chcieć wywołać 'std :: cout.flush()' przed 'Sleep()', ponieważ 'std :: cout' jest zbuforowanym strumieniem, a więc jego zawartość może nie być wyświetlana, gdy oczekujesz. –

+1

Jak mówi Dan, '\ r' jest karetką, która nie * usuwa * linii, po prostu przesuwa kursor z powrotem na początek linii. –

2

Podstawowym rozwiązaniem jest:

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

Alternatywnie, można spróbować rozwiązania z wykorzystaniem biblioteki curses - choć nie jestem pewien, czy jest to zupełnie co ty szukasz. Curses udostępnia podstawową grafikę ASCII dla tekstowych GUI (czasami nazywanych TUI).

+0

Klątwy to jedyny sposób na zrobienie tego portu. Zauważ, że twoja konsola jest częścią bazy danych curses. –

3

Klątwy to jedyny sposób, aby zrobić to przenośnie.

Wystarczy popatrzeć na to: http://code.google.com/p/tinycurses/wiki/basic1

+2

Nie powiedziałbym "tylko" sposób. Jeśli terminal jest zgodny z ANSI, możesz wyprowadzić "\ r" lub "\ 015". Jeśli jest kompatybilny z VT-100, możesz również wyprowadzić '\ 033 [5n' na TTY, a odpowiedź będzie miała postać '\ 033 [5; 5R', a następnie możesz wysłać '\ 033 [5; 0H ", aby przejść do początku linii 5. To wszystko robi i tak. – greyfade

+0

Jedyny ** przenośny ** sposób. Ponieważ lekarstwa wyabstrahują terminal, więc nie musisz znać jego kompatybilności z VT-100 ani cokolwiek innego. Możesz zrobić to, co opisujesz w niemal każdym terminalu, który musisz tylko przeglądać w dokumentacji i zrozumieć. To dlatego mamy przekleństwa ** ABSTRAKTY ** terminal, więc nie musisz wiedzieć, dlatego jest to jedyny ** PORTABLE ** sposób. OK są inne biblioteki (takie jak ncurses). O tak, po prostu pamiętałem, że ncurses to tylko przekleństwa, ale nowa wersja :-) –

0

Jak szybko są twoje cykle? Czy są w milisekundach, czy sekundach. Jeśli twoje cykle są krótkie, możesz chcieć zaktualizować ekran dopiero po upływie sekundy.

Na przykład

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

To tylko uaktualnić ekran każdy drugi i zaoszczędzić czas, pisząc na ekranie, ponieważ pochłania czas na przerysowanie ekranu (który można wykorzystać do przetworzenia). Ponadto, jeśli twoje aktualizacje idą tak szybko, to pozwala użytkownikowi zobaczyć procent, jeśli twoje cykle są dość krótkie, ponieważ możesz cały czas przerysowywać ekran.

Uwaga: Zaktualizowano na podstawie komentarzy.

+0

Potrzebuje czasu (0). time() pobiera adres time_t, aktualizując odniesiony time_t jeśli jest podany. –

+2

Lub możesz go zaktualizować, gdy wartość procentowa rzeczywiście rośnie, nie ma sensu go aktualizować, jeśli to samo będzie wyświetlane, a liczba połączeń nie przekroczy 101 (przy założeniu wyświetlania 0% -> 100%) , rysunek nie będzie miał dużego wpływu na wydajność –

+0

Dzięki za wejście. Minęło trochę czasu odkąd użyłem funkcji czasu. – Glenn

0

To zależy od platformy, z której korzystasz. Nie jestem pewien, jak to zrobić w systemie Linux, ale w systemie Windows można użyć do tego celu WriteConsole lub SetConsoleCursorPosition.

Nie wierzę, że całkowicie przenośny sposób na to działa, poza wypuszczaniem ton backspace, jak już wspomniano. Metoda backspace może powodować migotanie, które może być nie do przyjęcia w twojej aplikacji ... funkcje Win32 nie powodują migotania. Nie jestem pewien co do biblioteki curses.