c - guardar - manual vi
Borrar la lĂnea de consola impresa actual (9)
Acabo de encontrar este hilo viejo, buscando algún tipo de secuencia de escape para poner en blanco la línea real.
Es bastante divertido que nadie haya llegado a la idea (o me la he perdido) de que printf devuelve la cantidad de caracteres escritos. Tan solo imprima ''/ r'' + tantos caracteres en blanco como printf devuelto y exactamente vaciará el texto previamente escrito.
int BlankBytes(int Bytes)
{
char strBlankStr[16];
sprintf(strBlankStr, "/r%%%is/r", Bytes);
printf(strBlankStr,"");
return 0;
}
int main(void)
{
int iBytesWritten;
double lfSomeDouble = 150.0;
iBytesWritten = printf("test text %lf", lfSomeDouble);
BlankBytes(iBytesWritten);
return 0;
}
Como no puedo usar VT100, parece que tengo que seguir con esa solución
¿Cómo puedo borrar la línea de la consola impresa actual en C? Estoy trabajando en un sistema Linux. Por ejemplo -
printf("hello");
printf("bye");
Quiero imprimir bye en la misma línea en lugar de hola.
Algunas sutilezas que valen la pena ...
/33[2K
borra toda la línea en la que se encuentra el cursor actualmente
/033[A
mueve el cursor hacia arriba una línea, pero en la misma columna, es decir, no al comienzo de la línea
lleva el cursor al principio de la línea (r es para rebobinar) pero no borra nada
En xterm específicamente, probé las respuestas mencionadas anteriormente y la única forma que encontré para borrar la línea y comenzar de nuevo al principio es la secuencia (del comentario anterior publicado por @ Stephan202 y @vlp y @mantal) /33[2K/r
En una nota de implementación, para que funcione correctamente, por ejemplo, en un escenario de cuenta regresiva ya que no estaba usando un nuevo carácter de línea ''/n''
al final de cada fprintf()
, así que tuve que fflush()
el flujo cada tiempo (para darle un poco de contexto, comencé xterm usando un tenedor en una máquina Linux sin redireccionar stdout, solo estaba escribiendo en el fdfile
con un descriptor de archivo no bloqueante que tenía sentado en la dirección del pseudo terminal que en mi el caso fue /dev/pts/21
):
fprintf(fdfile, "/33[2K/rT minus %d seconds...", i);
fflush(fdfile);
Tenga en cuenta que utilicé la secuencia / 33 [2K para borrar la línea seguida de la secuencia /r
rebobinar para reposicionar el cursor al comienzo de la línea. Tuve que fflush()
después de cada fprintf()
porque no tengo un nuevo carácter de línea al final ''/n''
. El mismo resultado sin necesitar fflush () requeriría la secuencia adicional para subir una línea:
fprintf(fdfile, "/033[A/33[2K/rT minus %d seconds.../n", i);
Tenga en cuenta que si tiene algo en la línea inmediatamente superior a la línea en la que desea escribir, se sobrescribirá con el primer fprintf (). Tendría que dejar una línea adicional arriba para permitir el primer movimiento en una línea:
i = 3;
fprintf(fdfile, "/nText to keep/n");
fprintf(fdfile, "Text to erase****************************/n");
while(i > 0) { // 3 second countdown
fprintf(fdfile, "/033[A/33[2KT/rT minus %d seconds.../n", i);
i--;
sleep(1);
}
Este script está codificado para su ejemplo.
#include <stdio.h>
int main ()
{
//write some input
fputs("hello/n",stdout);
//wait one second to change line above
sleep(1);
//remove line
fputs("/033[A/033[2K",stdout);
rewind(stdout);
//write new line
fputs("bye/n",stdout);
return 0;
}
Haga clic aquí para obtener la source .
Hay un truco simple que puede trabajar aquí, pero necesita preparación antes de imprimir, tiene que poner lo que quiera imprimir en una variable y luego imprimir para saber la longitud para eliminar la cadena. Aquí hay un ejemplo.
#include <iostream>
#include <string> //actually this thing is not nessasory in tdm-gcc
using namespace std;
int main(){
//create string variable
string str="Starting count";
//loop for printing numbers
for(int i =0;i<=50000;i++){
//get previous string length and clear it from screen with backspace charactor
cout << string(str.length(),''/b'');
//create string line
str="Starting count " +to_string(i);
//print the new line in same spot
cout <<str ;
}
}
Por lo general, cuando aparece una ''/ r'' al final de la cadena, solo se imprime el retorno de carro sin ninguna nueva línea. Si tiene lo siguiente:
printf("fooooo/r");
printf("bar");
la salida será:
barooo
Una cosa que puedo sugerir (tal vez una solución) es tener una cadena de tamaño fijo terminada en NULL que se inicializa a todos los caracteres de espacio, terminando en ''/ r'' (cada vez antes de la impresión) y luego usar strcpy para copiar la cadena en (sin la nueva línea), por lo que cada impresión subsiguiente sobrescribirá la cadena anterior. Algo como esto:
char str[MAX_LENGTH];
// init str to all spaces, NULL terminated with character as ''/r''
strcpy(str, my_string); // copy my_string into str
str[strlen(my_string)] = '' ''; // erase null termination char
str[MAX_LENGTH - 1] = ''/r'';
printf(str);
Puedes hacer una comprobación de errores para que my_string
siempre tenga al menos una longitud menos que str
, pero obtienes la idea básica.
Puede usar los códigos de escape VT100 . La mayoría de los terminales, incluido xterm, son conscientes de VT100. Para borrar una línea, esto es ^[[2K
. En C esto da:
printf("%c[2K", 27);
Puede usar un /r
( retorno de carro ) para regresar el cursor al comienzo de la línea:
printf("hello");
printf("/rbye");
Esto se imprimirá en la misma línea. Sin embargo, no borrará los caracteres existentes, y como bye es más corto que hola , terminarás con byelo . Para borrarlo, puede hacer que la nueva impresión sea más larga para sobrescribir los caracteres adicionales:
printf("hello");
printf("/rbye ");
O bien, primero bórrelo con algunos espacios, luego imprima su nueva cadena:
printf("hello");
printf("/r ");
printf("/rbye");
Eso imprimirá hola , luego irá al principio de la línea y la sobreescribirá con espacios, luego volverá al principio e imprimirá adiós .
Puedes borrar la línea usando / b
printf("hello");
int i;
for (i=0; i<80; i++)
{
printf("/b");
}
printf("bye");
i
itera a través de palabras de conjunto de caracteres. j
realiza un seguimiento de la longitud de la palabra. "/b /b"
borra palabra mientras retrocede por línea.
#include<stdio.h>
int main()
{
int i = 0, j = 0;
char words[] = "Hello Bye";
while(words[i]!=''/0'')
{
if(words[i] != '' '') {
printf("%c", words[i]);
fflush(stdout);
}
else {
//system("ping -n 1 127.0.0.1>NUL"); //For Microsoft OS
system("sleep 0.25");
while(j-->0) {
printf("/b /b");
}
}
i++;
j++;
}
printf("/n");
return 0;
}