web-dev-qa-db-ja.com

バックスペース制御文字を使用した消去

バックスペース制御文字'\b'を使用して、行末の末尾のカンマを消去しようとしています。 stdoutへの他の出力がない場合でも機能しますが、'\b'の後に別の出力がある場合は、役に立たなくなります。次に例を示します。

#include <iostream>

using namespace std;

int main()
{
    int a[] =  { 1, 3, 4, 5, 6, 32, 321, 9};
    for ( int i = 0; i < 8; i++) {
        cout << a[i] << "," ;
    }
    cout << "\b" ;
    //cout << endl;
    return 0;
}

上記のコードブロックで、この行が見られるようにコメント化されている場合、9の後にカンマが付いていない目的の結果が得られます。

私のプログラムでは、コンマは必要ありませんが、9の後には最終行が必要です。これを行うにはどうすればよいですか?

19
hytriutucx

コンソールの最後の文字を消去する通常の方法は、シーケンス"\b \b"を使用することです。これにより、カーソルが1スペース後ろに移動し、次にスペースを書き込んで文字を消去し、もう一度バックスペースして新しい書き込みが古い位置から開始されるようにします。 \b自体はカーソルを移動するだけであることに注意してください。

もちろん、最初の場所でコンマを出力することを常に回避できます。

if(i > 0) cout << ",";
cout << a[i];
29
nneonneo

または、C + 11ハックが好きな場合:

adjacent_difference(a.begin(), a.end(), ostream_iterator<int>(std::cout),
  [](int x, int)->int { return std::cout << ",", x; });
4
rici

バックスペースエスケープシーケンスを使用すると、小さな問題が発生します。配列を印刷したいが、それを前もって定義している場合-そのサイズは常にゼロ以外です。ここで、配列、セット、リストなど、印刷するもののサイズがわからない場合を考えてください。すでにsthを印刷している場合。ものを印刷する前に、ゼロ要素を印刷することになっている場合、バックスペースはすでに印刷されているものを食い尽くします。

これを印刷して使用するためのメモリの場所と要素の数へのポインタが与えられていると仮定します...:

void printA(int *p, int count)
{
    std::cout << "elements = [";

    for (int i = 0; i < count; i++)
    {
        std::cout << p[i] << ",";
    }

    std::cout << "\b]\n";
}

...印刷する:

int tab[] = { 1, 2, 3, 4, 5, 6 };

printA(tab, 4);
printA(tab, 0); // <-- a problem

あなたは次のようになります:

elements = [1,2,3,4]
elements = ]

この特定のケースでは、開始ブラケットが「食べられました」。ループが0回実行される可能性があり、削除するカンマがないため、要素の後にカンマを出力せず、最後のカンマを削除することをお勧めします。代わりに、前にカンマを出力します-各要素の前にありますが、次のように最初のループの繰り返しをスキップします:

void printB(int *p, int count)
{
    std::cout << "elements = [";

    for (int i = 0; i < count; i++)
    {
        if (i != 0) std::cout << ',';
        std::cout << p[i];
    }

    std::cout << "]\n";
}

今このコード:

printB(tab, 4);
printB(tab, 0);

これを生成します:

elements = [1,2,3,4]
elements = []

バックスペースESCを使用。 seq。何を削除するかわからないだけです。

使用例

1
Artur