使用退格控制字符擦除

时间:2012-10-07 01:11:46

标签: c++ escaping

我正在尝试使用退格控制字符'\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之后需要一个结束语。我该怎么做?

4 个答案:

答案 0 :(得分:27)

擦除控制台上最后一个字符的常用方法是使用序列"\b \b"。这会将光标移回一个空格,然后写入一个空格来擦除字符,然后再次退格,以便新写入从旧位置开始。请注意,\b本身只会移动光标。

当然,你总是可以避免首先输出逗号:

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

答案 1 :(得分:4)

或者,如果你喜欢C + 11黑客:

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

答案 2 :(得分:0)

使用退格转义序列会导致较小的问题。如果要打印数组,并且已经预先定义了它-数组的大小总是非零。现在,假设您不知道数组,集合,列表或要打印的任何内容的大小,并且该大小可能为零。如果您已经打印过……。在打印东西之前,您应该打印零个元素,因此退格键会吞噬已经打印的东西。

假设您已获得指向内存位置和要打印并使用此元素的元素数量的指针:

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 = ]

在这种情况下,您的左括号被“吃掉”。 最好不要在元素后打印逗号并删除最后一个逗号,因为循环可能执行零次并且没有逗号要删除。而是在每个元素之前打印逗号-是在每个元素之前-但是跳过第一次循环迭代-像这样:

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。您永远不知道自己会删除什么。

working example

答案 3 :(得分:-1)

是的,\ b只会移动诅咒,所以当你结束这条线时,它只会将它移回到线的末端。所以要实际擦除最后一部分后有一个空格\ b实际上擦除了最后一个逗号。例如:cout&lt;&lt;“\ b”;