#c #console-application #carriage-return
#c #консольное приложение #возврат каретки
Вопрос:
Предположим, у меня есть следующий код, который является бесконечным счетчиком :
#include <iostream>
int main() {
short int counter = 0;
while(true)
cout << "This is a counter: " << counter << " and I'll keep counting!r";
return 0;
}
Когда вы запускаете код с возвратом каретки, он перезапишет существующий текст, но в конце будет больше одного ‘!’. Есть ли способ исправить это, не вызывая clear screen, чтобы избежать мерцания?
Комментарии:
1. «Напечатайте» в строку и дополните ее пробелами в конце, чтобы она была как минимум такой же длины, как предыдущая строка. Затем выведите строку. Или, поскольку вы знаете, что короткое целое число со знаком не может быть длиннее пяти символов (
32767
), вы можете убедиться, что строка всегда дополняется для правильной длины.2. Добавьте несколько пробелов после восклицательного знака.
3. Тем не менее, немного озадачен. Как может быть оставшийся восклицательный знак, если счетчик постоянно увеличивается?
4. @Dialecticus это короткий int, он переполнится и вернется из отрицательного
5. Если используется VT-совместимый выходной терминал (большинство из них), добавьте
cout << "33[0k" << ...
, который является экранированием ANSI, в «Очистить до конца строки» .
Ответ №1:
Продолжая приведенные выше комментарии, если вы выводите данные на терминал, совместимый с VT (большинство из них), вы можете использовать Escape-последовательности ANSI для управления очисткой до конца строки (и различными другими движениями курсора и видимостью).
Краткий пример работы со строками, заканчивающимися возвратом каретки, который можно использовать 33[K
для очистки до конца строки. (формальное число, предшествующее 'K'
"0K"
, но может быть опущено из-за того, что оно используется по умолчанию) Другие варианты очистки строки "1K"
— очистить начало строки и "2K"
очистить всю строку. Вы также можете скрыть и восстановить курсор с помощью аналогичных экранирований.
В вашем случае вы можете обрабатывать дополнительные символы из предыдущих более длинных строк как:
#include <iostream>
#include <unistd.h>
int main (void) {
const char *lines[] = { "You do not ever wantr",
"your favorite dogr",
"to haver",
"fleas!r" };
int n = sizeof lines / sizeof *lines;
std::cout << "33[?25l"; /* hide cursor */
for (int i = 0; i < n; i ) {
std::cout << "33[0K" << lines[i]; /* clear to end, output line */
std::fflush (stdout);
sleep (2);
}
std::cout << "33[?25hn"; /* restore cursor */
}
Скомпилируйте нормально и запустите в своем терминале. Если он совместим с VT, он обработает экранирование, чтобы вы видели, что каждая строка печатается без каких-либо дополнительных символов из предыдущей строки, мешающих выводу.
Ответ №2:
Вы могли бы сначала написать строку из одних пробелов до «максимальной» ожидаемой длины, саму с a r
в конце.
Кроме того, на каждой итерации подсчитывайте, сколько пробелов вам может потребоваться для заполнения конца новой строки, чтобы достичь этого максимума.