2009-09-02 3 views
5

Приношу извинения за неточное название, но я не уверен, что именно это называется.Печать на консоль без наводнения в C++

Как распечатать на консоль одну, обновив строку?

Например, если бы я хотел распечатать процентный статус завершения каждый цикл, но не наводнять консоль парой текста, как бы это сделать? (Что это называется? - для будущего Googling)

Спасибо!

ответ

11

Там нет переносимого способа очистки экрана, хотя есть простой способ, чтобы вернуться к началу линии с помощью \r затем перезаписать то, что мы писали ранее. Я использую Sleep из 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

Для дополнительного освещения '\ r' выводит возврат каретки. –

+6

Возможно, вы захотите вызвать 'std :: cout.flush()' перед 'Sleep()', поскольку 'std :: cout' является буферизованным потоком и, следовательно, его содержимое может не отображаться, когда вы ожидаете. –

+1

Как говорит Дэн, '\ r' - это возврат каретки, который не * очищает * линию, он просто перемещает курсор обратно в начало строки. –

2

Основное решение заключается в следующем:

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

В качестве альтернативы, вы можете попробовать решение с использованием библиотеки проклятия - хотя я не уверен, является ли совсем то, что вы после. Curses предоставляет базовую графику ascii для текстовых графических интерфейсов (иногда называемых TUI).

+0

Curses - единственный способ умереть этим портом. Обратите внимание, что предполагается, что ваша консоль является частью базы данных curses. –

3

Curses - это единственный способ сделать это переносимо.

Посмотрите на это: http://code.google.com/p/tinycurses/wiki/basic1

+2

Я бы не сказал «единственный» способ. Если терминал ANSI-совместим, вы можете вывести «\ r» или «\ 015». Если он совместим с VT-100, вы также можете вывести '\ 033 [5n' в TTY, и ответ будет соответствовать строкам '\ 033 [5; 5R', а затем вы можете отправить '\ 033 [5; 0H ', чтобы перейти к началу строки 5. Это все ncurses все равно. – greyfade

+0

Единственный ** портативный ** способ. Потому что лечение абстрагирует терминал, поэтому вам не нужно знать его совместимость с VT-100 или что-то еще. Вы можете делать то, что вы описываете, в каком-либо терминале, который вам просто нужно, чтобы просмотреть документацию и понять ее. Вот почему мы проклинали это ** АБСТРАКТЫ ** терминал, поэтому вам не нужно знать, таким образом, является единственным ** ПОРТАТИВНЫМ ** способом. ОК есть другие библиотеки (например, ncurses). О да только что вспомнил ncurses - это просто проклятия, но новая версия :-) –

0

Как быстро ваши циклы? Являются ли они в миллисекундах или секундах. Если ваши циклы коротки, вам может потребоваться обновить экран только через секунду.

Например

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

Это будет обновлять только на экране каждую секунду и сэкономить время записи на экране, как он потребляет время перерисовки экрана (который вы можете использовать для обработки). Кроме того, если ваши обновления идут так быстро, это позволяет пользователю увидеть процент, если ваши циклы довольно короткие, так как вы могли постоянно перерисовывать экран.

Примечание: Обновлено на основе комментариев.

+0

Нужно быть время (0). time() принимает адрес time_t, обновляя ссылочный time_t, если задано. –

+2

Или вы могли бы просто обновить его, когда процент на самом деле увеличивается, нет смысла обновлять его, если будет отображаться то же самое, и с количеством обратных вызовов, не прошедших 101 (при условии отображения 0% -> 100%), , рисунок не будет иметь большого влияния на производительность. –

+0

Спасибо за ввод. Прошло некоторое время с тех пор, как я использовал функцию времени. – Glenn

0

Это зависит от платформы, которую вы используете. Я не уверен, как вы это делаете в Linux, но для Windows вы можете использовать WriteConsole или SetConsoleCursorPosition.

Я не верю, что полностью переносимый способ сделать это существует, кроме вывода тонны обратных пространств, как уже упоминалось. Метод backspace может вызвать много мерцания, которое может быть неприемлемым в вашем приложении ... функции Win32 не вызывают мерцания. Не уверен в библиотеке curses.

 Смежные вопросы

  • Нет связанных вопросов^_^