Ответ 1
попробуйте использовать \r
вместо \n
при печати новой "версии".
for(int i=0;i<=100;++i) printf("\r[%3d%%]",i);
printf("\n");
Я хочу сделать индикатор выполнения для моего приложения терминала, который будет работать примерно так:
[XXXXXXX ]
который даст визуальную индикацию того, сколько времени осталось до завершения процесса.
Я знаю, что могу делать что-то вроде печати все больше и больше X, добавляя их в строку, а затем просто printf, но это будет выглядеть так:
[XXXXXXX ]
[XXXXXXXX ]
[XXXXXXXXX ]
[XXXXXXXXXX ]
или что-то в этом роде (очевидно, вы можете играть с интервалом.) Но это не визуально эстетично. Есть ли способ обновить напечатанный текст в терминале с новым текстом без переиздания? Это все под linux, С++.
попробуйте использовать \r
вместо \n
при печати новой "версии".
for(int i=0;i<=100;++i) printf("\r[%3d%%]",i);
printf("\n");
Я бы сказал, что для таких вещей будет использоваться библиотека, такая как ncurses. curses помогает перемещать курсор вокруг экрана и рисовать текст и т.д.
Что-то вроде этого:
std::stringstream out;
for (int i = 0; i< 10; i++)
{
out << "X";
cout << "\r" << "[" << out.str() << "]";
}
Скрытый бит - это символ возврата каретки "\ r", который заставляет курсор перемещаться в начало строки, не переходя к следующей строке.
Другие уже указали, что вы можете использовать \r
для возврата к началу текущей строки и перезаписать всю строку.
Другая возможность заключается в использовании символа backspace ( "\ b" ) для удаления нескольких пробелов и перезаписи только тех пробелов. Это может иметь несколько преимуществ. Во-первых, он, очевидно, избегает необходимости регенерировать все в линии, что иногда может быть слегка болезненным (хотя это довольно необычно). Во-вторых, он может избежать некоторой боли при отображении данных, которые (на одном примере) уменьшаются по размеру, когда вы его пишете, например, если вы показываете обратный отсчет от 100 до 0, с \r
вы должны быть осторожно переписывая всю предыдущую длину, или ваш обратный отсчет будет идти от (например) от 100 до 990 (т.е. оставит прежний "0" неповрежденным).
Обратите внимание, однако, что, хотя back-space внутри строки нормально работает, backspace в начале строки может или не может перемещать позицию курсора/записи назад в предыдущую строку. Для большинства практических целей вы можете перемещаться только в одной строке.
'\ r' выполнит возврат каретки. Представьте, что принтер выполняет возврат каретки без перевода строки ('\n'). Это вернет точку записи обратно к началу строки... затем перепечатайте обновленный статус поверх исходной строки.
Это другой язык, но этот вопрос может вам помочь. В принципе, escape-символ\r (возврат каретки, в отличие от \n Newline) возвращает вас к началу вашей текущей печатной строки, чтобы вы могли перезаписать то, что вы уже напечатали.
Другой вариант - просто напечатать один символ за раз. Как правило, stdout является строковым буфером, поэтому вам нужно вызвать fflush (stdout) -
for(int i = 0; i < 50; ++i) {
putchar('X'); fflush(stdout);
/* do some stuff here */
}
putchar('\n');
Но это не имеет прекрасного завершения "]", который указывает на завершение.