При создании приложения консоли Windows в C # можно ли писать в консоль без необходимости расширения текущей строки или перехода на новую строку? Например, если я хочу показать процент, показывающий, насколько близок процесс к завершению, я просто хотел бы обновить значение в той же строке, что и курсор, и не нужно помещать каждый процент в новую строку.
Можно ли это сделать с помощью «стандартного» консольного приложения C #?
Ответы:
Если вы печатаете только
"\r"
на консоль, курсор возвращается к началу текущей строки, а затем вы можете переписать его. Это должно сделать трюк:Обратите внимание на несколько пробелов после числа, чтобы убедиться, что все, что было раньше, стерто.
Также обратите внимание на использование
Write()
вместо,WriteLine()
так как вы не хотите добавлять "\ n" в конце строки.источник
PadRight
(сохранение сначала незаполненной строки или длины, конечно же).Вы можете использовать
Console.SetCursorPosition
для установки позиции курсора, а затем писать в текущей позиции.Вот пример, показывающий простой «спиннер»:
Обратите внимание, что вам нужно будет обязательно перезаписать любой существующий вывод новым выводом или пробелами.
Обновление: так как критиковалось, что пример перемещает курсор назад только на один символ, я добавлю это для пояснения: используя
SetCursorPosition
вы можете установить курсор в любую позицию в окне консоли.установит курсор на начало текущей строки (или вы можете использовать
Console.CursorLeft = 0
напрямую).источник
SetCursorPosition
(илиCursorLeft
) обеспечивает большую гибкость, например, не писать в начале строки, перемещаться вверх по окну и т. Д., Так что это более общий подход, например, для вывода пользовательские индикаторы выполнения или ASCII-графика.Пока у нас есть три конкурирующих альтернативы, как это сделать:
Я всегда использовал
Console.CursorLeft = 0
вариант третьего варианта, поэтому я решил провести несколько тестов. Вот код, который я использовал:На моей машине я получаю следующие результаты:
Кроме того,
SetCursorPosition
вызвал заметное мерцание, которое я не наблюдал ни с одной из альтернатив. Итак, мораль в том, чтобы использовать возвраты или возврат каретки, когда это возможно , и спасибо, что научили меня более быстрому способу сделать это, ТАК!Обновление : в комментариях Джоэл предлагает, чтобы SetCursorPosition было постоянным относительно расстояния, в то время как другие методы являются линейными. Дальнейшее тестирование подтверждает, что это так, однако постоянное время и медленный процесс все еще медленный. В моих тестах запись длинной строки возврата на консоль выполнялась быстрее, чем SetCursorPosition, примерно до 60 символов. Так что backspace быстрее для замены частей строки короче 60 символов (или около того), и он не мерцает, поэтому я буду придерживаться моего первоначального одобрения \ b над \ r и
SetCursorPosition
.источник
Вы можете использовать escape-последовательность \ b (backspace) для резервного копирования определенного количества символов в текущей строке. Это просто перемещает текущее местоположение, но не удаляет символы.
Например:
Здесь строка - это процентная строка для записи в консоль. Хитрость заключается в том, чтобы сгенерировать правильное количество символов \ b для предыдущего вывода.
Преимущество этого подхода по сравнению с \ r заключается в том, что if работает, даже если ваш процентный вывод находится не в начале строки.
источник
\r
используется для этих сценариев.\r
представляет возврат каретки, что означает, что курсор возвращается в начало строки.Вот почему Windows использует в
\n\r
качестве маркера новой строки.\n
перемещает вас вниз по линии и\r
возвращает вас к началу строки.источник
Я просто должен был играть с
ConsoleSpinner
классом диво . У меня далеко не все так лаконично, но мне просто не понравилось, что пользователи этого класса должны написать свой собственныйwhile(true)
цикл. Я снимаюсь для опыта, похожего на это:И я понял это с кодом ниже. Поскольку я не хочу, чтобы мой
Start()
метод блокировался, я не хочу, чтобы пользователю приходилось беспокоиться о написанииwhile(spinFlag)
цикла -подобного типа, и я хочу разрешить одновременное использование нескольких спиннеров, мне пришлось порождать отдельный поток для обработки спиннинг. А это значит, что код должен быть намного сложнее.Кроме того, я не сделал так много многопоточности, поэтому возможно (вероятно, даже), что я оставил небольшую ошибку или три там. Но, похоже, пока работает довольно хорошо:
источник
Явное использование возврата каретки (\ r) в начале строки, а не (неявно или явно) использование новой строки (\ n) в конце должно получить то, что вы хотите. Например:
источник
источник
Из Консоли в MSDN:
Итак - я сделал это:
Тогда я могу сам контролировать выход;
Еще один способ добраться туда.
источник
Это работает, если вы хотите, чтобы генерирующие файлы выглядели круто.
И это метод, который я получил из некоторого ответа ниже и изменил его
источник
Вот еще один: D
источник
Если вы хотите обновить одну строку, но информация слишком длинна, чтобы отображаться в одной строке, возможно, потребуются новые строки. Я столкнулся с этой проблемой, и ниже представлен один из способов ее решения.
источник
я искал такое же решение в vb.net, и я нашел это, и это здорово.
однако @JohnOdom предложил лучший способ обработки пробелов, если предыдущий больше текущего.
я сделал функцию в vb.net и думал, что кто-то может помочь
вот мой код:
источник
Static intLastLength As Integer
.Я искал это, чтобы понять, может ли написанное мной решение оптимизироваться по скорости. Я хотел таймер обратного отсчета, а не просто обновление текущей строки. Вот что я придумал. Может быть полезным для кого-то
источник
Вдохновленный @ E.Lahu Solution, реализация индикатора прогресса в процентах.
источник
Вот мой взгляд на ответы s soosh и 0xA3. Он может обновлять консоль пользовательскими сообщениями при обновлении счетчика, а также имеет индикатор истекшего времени.
использование примерно так:
источник
SetCursorPosition
Метод работает в многопоточном сценарии, где две другие методы неисточник