Подтвердить что ты не робот

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

Я хочу вывести на stdout и вывести "перезаписать" предыдущий вывод.

Например; если я вывешу On 1/10, я хочу, чтобы следующий выход On 2/10 перезаписывал On 1/10. Как я могу это сделать?

4b9b3361

Ответ 1

stdout - это поток (io.Writer). Вы не можете изменить то, что уже было записано в него. Что может быть изменено, так это то, как этот поток отображается в случае его печати на терминале. Обратите внимание, что нет веских оснований предполагать такой сценарий. Например, пользователь может перенаправить стандартный вывод в канал или в файл по желанию.

Поэтому правильный подход - сначала проверить:

  • если стандартный вывод идет в терминал
  • что это за процедура терминала для перезаписи строки/экрана

Оба вышеперечисленных вопроса выходят за рамки этого вопроса, но давайте предположим, что терминалом является наше устройство. Затем обычно печатают:

fmt.Printf("\rOn %d/10", i)

перезапишет предыдущую строку в терминале. \r означает carriage return, реализуемый многими терминалами как перемещение курсора к началу текущей строки, что обеспечивает возможность перезаписи строки.

В качестве примера "другого" терминала с по-разному поддерживаемой "перезаписью", вот пример на игровой площадке.

Ответ 2

Используйте это решение, если вы хотите переписать несколько строк на вывод. Например, я сделал достойный Conway "Game of Life" с помощью этого метода.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: это работает только на терминалах ANSI, и, кроме того, используя fmt, это также не ответ на вопрос Go.

fmt.Printf("\033[0;0H")
// put your other fmt.Printf(...) here

Краткое пояснение: это escape-последовательность, которая сообщает терминалу ANSI переместить курсор в определенное место на экране. \033[ - это так называемая escape-последовательность, а 0;0H - тип кода, указывающий, что терминал переводит курсор в строку 0, столбец 0 терминала.

Источник: https://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements

Ответ 3

Решение для одной строки, которая заменит всю строку

fmt.Printf("\033[2K\r%d", i)

Например, он правильно печатает от 10 до 0:

for i:= 10; i>=0; i-- {
    fmt.Printf("\033[2K\r%d", i)
    time.Sleep(1 * time.Second)
}
fmt.Println()

какие предыдущие ответы не решают.