ANSI转义码ESC [0E不能按预期工作

时间:2014-08-18 03:48:30

标签: terminal ansi-escape

我正在尝试this answer的示例代码。

#include <iostream>
#include <thread>
#include <chrono>

void drawProgressBar(int, double);

int main() {

    drawProgressBar(30, .25);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    drawProgressBar(30, .50);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    drawProgressBar(30, .75);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    drawProgressBar(30, 1);

    return 0;
}

void drawProgressBar(int len, double percent) {
    std::cout << "\x1B[2K"; // Erase the entire current line.
    std::cout << "\x1B[0E"; // Move to the beginning of the current line.
    std::string progress;
    for (int i = 0; i < len; ++i) {
        if (i < static_cast<int>(len * percent)) {
            progress += "=";
        } else {
            progress += " ";
        }
    }
    std::cout << "[" << progress << "] " << (static_cast<int>(100 * percent)) << "%" << std::flush;
}

预期的行为是一个进度条,如下所示:

[=======                       ] 25%

会在同一行上更新三次,最后为:

[==============================] 100%

3秒后。

当每个进度条按预期被删除时,下一个进度条会向下绘制一行,而不是与我期望的相同。

答案(Wikipedia)中链接的文档说CSI n EESC[nE)其中n是一个整数:

  

将光标移动到第n行(默认为1)行的开头。

所以我希望CSI 0 EESC[0E)将光标移动到当前行的开头(行0行)。

为什么不呢?另外,我怎样才能达到预期的行为?


我在OS X上使用Terminal.app来运行此程序。

1 个答案:

答案 0 :(得分:1)

嗯,试试:

std::cout << "\r";

而不是:

std::cout << "\x1B[2K"; // Erase the entire current line.
std::cout << "\x1B[0E"; // Move to the beginning of the current line.

这是回车,应该将光标重新定位在该行的开头。

(顺便说一句,感谢您对代码进行评论。喜欢人们在这里做的事情:))