104 votes

Effacer la ligne actuellement affichée dans la console

Comment puis-je effacer la ligne actuellement imprimée dans la console en C ? Je travaille sur un système Linux. Par exemple -

printf("hello");
printf("bye");

Je veux afficher bye sur la même ligne à la place de hello.

119voto

mouviciel Points 36624

Vous pouvez utiliser les codes d'échappement VT100. La plupart des terminaux, y compris xterm, sont compatibles VT100. Pour effacer une ligne, utilisez ^[[2K. En C, cela donne :

printf("\33[2K\r");

72voto

J-a-n-u-s Points 658

Quelques subtilités valant la peine d'être mentionnées...

\33[2K efface toute la ligne sur laquelle se trouve actuellement votre curseur

\033[A déplace votre curseur d'une ligne vers le haut, mais dans la même colonne, c'est-à-dire pas au début de la ligne

\r ramène votre curseur au début de la ligne (r signifie retour chariot N.B. les retours chariot n'incluent pas de saut de ligne donc le curseur reste sur la même ligne) mais ne efface rien

Plus spécifiquement dans xterm, j'ai essayé les réponses mentionnées ci-dessus et la seule façon que j'ai trouvée pour effacer la ligne et recommencer au début est la séquence (du commentaire ci-dessus posté par @Stephan202 ainsi que @vlp et @mantal) \33[2K\r

Sur une note d'implémentation, pour que cela fonctionne correctement par exemple dans un scénario de compte à rebours étant donné que je n'utilisais pas de caractère de nouvelle ligne '\n' à la fin de chaque fprintf(), j'ai dû utiliser fflush() le flux à chaque fois (pour vous donner un contexte, j'ai démarré xterm en utilisant un fork sur une machine Linux sans rediriger stdout, j'écrivais simplement sur le pointeur de fichier mis en mémoire tampon fdfile avec un descripteur de fichier non bloquant que j'avais sur l'adresse du pseudo terminal qui dans mon cas était /dev/pts/21):

fprintf(fdfile, "\33[2K\rT moins %d secondes...", i);
fflush(fdfile);

Remarquez que j'ai utilisé à la fois la séquence \33[2K pour effacer la ligne suivie de la séquence \r retour chariot pour repositionner le curseur au début de la ligne. J'ai dû utiliser fflush() après chaque fprintf() car je n'avais pas de caractère de nouvelle ligne à la fin '\n'. Le même résultat sans nécessiter fflush() nécessiterait la séquence supplémentaire pour remonter d'une ligne :

fprintf(fdfile, "\033[A\33[2K\rT moins %d secondes...\n", i);

Remarquez que si vous avez quelque chose sur la ligne immédiatement au-dessus de celle sur laquelle vous voulez écrire, il sera écrasé avec le premier fprintf(). Vous devrez laisser une ligne supplémentaire au-dessus pour permettre le premier déplacement d'une ligne vers le haut:

i = 3;
fprintf(fdfile, "\nTexte à conserver\n");
fprintf(fdfile, "Texte à effacer****************************\n");
while(i > 0) { // Compte à rebours de 3 secondes
    fprintf(fdfile, "\033[A\33[2KT\rT moins %d secondes...\n", i);
    i--;
    sleep(1);
}

62voto

Andre Miller Points 6713

Vous pouvez utiliser un \r (retour chariot) pour ramener le curseur au début de la ligne :

printf("hello");
printf("\rbye");

Cela affichera bye sur la même ligne. Cependant, cela n'effacera pas les caractères existants, et comme bye est plus court que hello, vous obtiendrez byelo. Pour l'effacer, vous pouvez rendre votre nouvelle impression plus longue pour écraser les caractères supplémentaires :

printf("hello");
printf("\rbye  ");

Ou, effacez d'abord avec quelques espaces, puis imprimez votre nouvelle chaîne :

printf("hello");
printf("\r          ");
printf("\rbye");

Cela affichera hello, puis retournera au début de la ligne et l'écrasera avec des espaces, puis reviendra au début et imprimera bye.

4voto

alexander.egger Points 1330

Vous pourriez supprimer la ligne en utilisant \b

printf("hello");
int i;
for (i=0; i<80; i++)
{
  printf("\b");
}
printf("bye");

4voto

Wil Shipley Points 5327

Quand j'étais jeune, nous avions une bibliothèque appelée "curses" qui vous permettait de dessiner partout sur l'écran avec des caractères, car nous n'avions pas encore inventé les graphismes.

Je crois qu'il fallait d'abord passer en mode plein écran, mais cette restriction a peut-être été levée depuis. De plus, sur Linux, elle pourrait ne pas s'appeler 'curses'.

-Wil

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X