82

Cで現在印刷されているコンソール行を消去するにはどうすればよいですか? Linuxシステムで作業しています。例えば ​​-

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

hello の代わりに同じ行に bye を出力したい。

4

12 に答える 12

82

VT100 エスケープ コードを使用できます。xterm を含むほとんどの端末は、VT100 対応です。線を消すには^[[2K. C では、次のようになります。

printf("\33[2K\r");
于 2009-10-02T09:33:30.510 に答える
61

\r(改行) を使用して、カーソルを行頭に戻すことができます。

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

これにより、同じ行にbyeが出力されます。ただし、既存の文字は消去されず、byeはhelloよりも短いため、byeloになります。それを消去するには、新しいプリントを長くして余分な文字を上書きすることができます:

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

または、最初にいくつかのスペースで消去してから、新しい文字列を出力します。

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

helloが出力され、行の先頭に移動してスペースで上書きされ、再び先頭に戻ってbyeが出力されます。

于 2009-10-02T09:14:44.760 に答える
56

いくつかの価値のある微妙な点...

\33[2K現在カーソルがある行全体を消去します

\033[Aカーソルを1行上に移動しますが、同じ列、つまり行の先頭には移動しません

\rカーソルを行の先頭に移動します (r はキャリッジ リターンです。注意: キャリッジ リターンには改行が含まれていないため、カーソルは同じ行に残ります)。ただし、何も消去しません。

特にxtermでは、上記の返信を試しましたが、行を消去して最初からやり直すことがわかった唯一の方法は、シーケンスです(@Stephan202と@vlpおよび@mantalによって投稿された上記のコメントから)\33[2K\r

'\n' 実装ノートでは、たとえばカウントダウン シナリオで適切に機能させるために、 each の最後に改行文字を使用してfprintf()いなかったので、毎回fflush()ストリームする必要がありました (コンテキストを提供するために、始めましたstdoutをリダイレクトせずにLinuxマシンでフォークを使用してxtermを実行するfdfileと、疑似端末アドレスに座っていた非ブロッキングファイル記述子を使用して、バッファリングされたFILEポインターに書き込みました/dev/pts/21

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

\33[2K シーケンスを使用して行を消去し、続いて\rキャリッジ リターン シーケンスを使用してカーソルを行頭に再配置したことに注意してください。最後に改行文字がないのでfflush()、それぞれの後にしなければなりませんでした。fflush() を必要とせずに同じ結果を得るには、追加のシーケンスを 1 行上に移動する必要があります。fprintf()'\n'

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

書き込みたい行のすぐ上の行に何かがある場合、最初の fprintf() で上書きされることに注意してください。最初に 1 行上に移動できるように、上に余分な行を残す必要があります。

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);
}
于 2016-02-04T00:17:24.717 に答える
4

\bを使用して行を削除できます

printf("hello");
int i;
for (i=0; i<80; i++)
{
  printf("\b");
}
printf("bye");
于 2009-10-02T09:24:52.053 に答える
3

通常、文字列の末尾に「\ r」がある場合、改行なしでキャリッジリターンのみが出力されます。次の場合:

printf("fooooo\r");
printf("bar");

出力は次のようになります。

barooo

私が提案できることの1つ(おそらく回避策)は、すべてのスペース文字に初期化され、「\ r」で終わる(印刷前に毎回)NULLで終了する固定サイズの文字列を作成し、strcpyを使用して文字列をにコピーすることです。 (改行なしで)したがって、後続のすべての印刷は前の文字列を上書きします。このようなもの:

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);

エラーチェックを実行して、my_string常に少なくとも1つ短い長さstrにすることができますが、基本的な考え方は理解できます。

于 2009-10-02T09:22:47.577 に答える
2

ichar配列の単語を反復処理します。 j単語の長さを追跡します。 "\b \b"行をバックアップしながら単語を消去します。

#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;
}
于 2012-02-17T23:41:23.127 に答える
2

このスクリプトは、例のためにハードコーディングされています。

#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;
}

ソースはここをクリックしてください。

于 2015-07-14T11:17:09.723 に答える
1

ここで作業できる簡単なトリックがありますが、印刷する前に準備が必要です。印刷したいものを変数に入れてから印刷して、文字列を削除する長さを知る必要があります。例を次に示します。

#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 ;
    }

}
于 2016-03-29T07:05:38.630 に答える