Al crear una aplicación de consola de Windows en C #, ¿es posible escribir en la consola sin tener que extender una línea actual o ir a una nueva? Por ejemplo, si quiero mostrar un porcentaje que represente qué tan cerca está un proceso de completarse, me gustaría actualizar el valor en la misma línea que el cursor y no tener que poner cada porcentaje en una nueva línea.
¿Se puede hacer esto con una aplicación de consola C # "estándar"?
Respuestas:
Si imprime solo
"\r"
en la consola, el cursor vuelve al comienzo de la línea actual y luego puede reescribirlo. Esto debería funcionar:Observe los pocos espacios después del número para asegurarse de que se borre todo lo que había antes.
Observe también el uso de en
Write()
lugar deWriteLine()
ya que no desea agregar un "\ n" al final de la línea.fuente
PadRight
(guardar la cadena sin relleno, o longitud, primero, por supuesto).Puede usar
Console.SetCursorPosition
para establecer la posición del cursor y luego escribir en la posición actual.Aquí hay un ejemplo que muestra un simple "spinner":
Tenga en cuenta que deberá asegurarse de sobrescribir cualquier salida existente con nueva salida o espacios en blanco.
Actualización: como se ha criticado que el ejemplo mueve el cursor solo un carácter hacia atrás, agregaré esto para aclararlo: al usarlo
SetCursorPosition
, puede colocar el cursor en cualquier posición en la ventana de la consola.configurará el cursor al comienzo de la línea actual (o puede usarlo
Console.CursorLeft = 0
directamente).fuente
SetCursorPosition
(oCursorLeft
) permite una mayor flexibilidad, por ejemplo, no escribir al comienzo de la línea, subir en la ventana, etc., por lo que es un enfoque más general que puede usarse para, por ejemplo, la salida barras de progreso personalizadas o gráficos ASCII.Hasta ahora tenemos tres alternativas competitivas sobre cómo hacer esto:
Siempre he usado
Console.CursorLeft = 0
una variación de la tercera opción, así que decidí hacer algunas pruebas. Aquí está el código que usé:En mi máquina, obtengo los siguientes resultados:
Además,
SetCursorPosition
causó un notable parpadeo que no observé con ninguna de las alternativas. Por lo tanto, la moraleja es usar espacios de retroceso o retornos de carro cuando sea posible , y gracias por enseñarme una forma más rápida de hacer esto, ¡SO!Actualización : en los comentarios, Joel sugiere que SetCursorPosition es constante con respecto a la distancia movida mientras que los otros métodos son lineales. Pruebas adicionales confirman que este es el caso, sin embargo , el tiempo constante y lento aún es lento. En mis pruebas, escribir una larga cadena de espacios de retroceso en la consola es más rápido que SetCursorPosition hasta aproximadamente 60 caracteres. Entonces, el retroceso es más rápido para reemplazar porciones de la línea de menos de 60 caracteres (más o menos), y no parpadea, por lo que voy a mantener mi respaldo inicial de \ b sobre \ r y
SetCursorPosition
.fuente
Puede usar la secuencia de escape \ b (retroceso) para hacer una copia de seguridad de un número particular de caracteres en la línea actual. Esto solo mueve la ubicación actual, no elimina los caracteres.
Por ejemplo:
Aquí, línea es el porcentaje de línea para escribir en la consola. El truco consiste en generar el número correcto de caracteres \ b para la salida anterior.
La ventaja de esto sobre el enfoque \ r es que funciona incluso si su porcentaje de salida no está al comienzo de la línea.
fuente
\r
se usa para estos escenarios.\r
representa un retorno de carro, lo que significa que el cursor vuelve al inicio de la línea.Es por eso que Windows usa
\n\r
como su nuevo marcador de línea.\n
te mueve hacia abajo una línea y\r
te regresa al comienzo de la línea.fuente
Solo tenía que jugar con la
ConsoleSpinner
clase del divo . El mío no es tan conciso, pero no me pareció bien que los usuarios de esa clase tengan que escribir su propiowhile(true)
bucle. Estoy filmando para una experiencia más como esta:Y me di cuenta con el siguiente código. Como no quiero que mi
Start()
método se bloquee, no quiero que el usuario tenga que preocuparse por escribir unwhile(spinFlag)
bucle similar, y quiero permitir que varias hiladoras al mismo tiempo tengan que generar un hilo separado para manejar el hilado. Y eso significa que el código tiene que ser mucho más complicado.Además, no he hecho tantos subprocesos múltiples, por lo que es posible (incluso probable) que haya dejado un error sutil o tres allí. Pero parece funcionar bastante bien hasta ahora:
fuente
El uso explícito de un Retorno de Carrage (\ r) al comienzo de la línea en lugar de (implícita o explícitamente) el uso de una Nueva Línea (\ n) al final debería obtener lo que desea. Por ejemplo:
fuente
fuente
Desde los documentos de la consola en MSDN:
Entonces, hice esto:
Entonces puedo controlar la salida yo mismo;
Otra forma de llegar allí.
fuente
Esto funciona si desea que la generación de archivos se vea genial.
Y este es el método que obtuve de alguna respuesta a continuación y la modifiqué
fuente
Aquí hay otro: D
fuente
Si desea actualizar una línea, pero la información es demasiado larga para mostrarse en una línea, es posible que necesite algunas líneas nuevas. Me he encontrado con este problema, y a continuación hay una forma de resolverlo.
fuente
Estaba buscando la misma solución en vb.net y encontré esta y es genial.
sin embargo, como @JohnOdom sugirió una mejor manera de manejar el espacio en blanco si el anterior es más grande que el actual.
hice una función en vb.net y pensé que alguien podría recibir ayuda ...
Aquí está mi código:
fuente
Static intLastLength As Integer
.Estaba haciendo una búsqueda de esto para ver si la solución que escribí podría optimizarse para la velocidad. Lo que quería era un temporizador de cuenta regresiva, no solo actualizar la línea actual. Esto es lo que se me ocurrió. Puede ser útil para alguien
fuente
Inspirado por @ E.Lahu Solution, implementación de una barra de progreso con porcentaje.
fuente
Aquí está mi opinión sobre las respuestas de s soosh y 0xA3. Puede actualizar la consola con mensajes de usuario mientras actualiza la ruleta y también tiene un indicador de tiempo transcurrido.
el uso es algo como esto:
fuente
El
SetCursorPosition
método funciona en un escenario de subprocesos múltiples, donde los otros dos métodos nofuente