我正在尝试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 E
(ESC[nE
)其中n
是一个整数:
将光标移动到第n行(默认为1)行的开头。
所以我希望CSI 0 E
(ESC[0E
)将光标移动到当前行的开头(行0
行)。
为什么不呢?另外,我怎样才能达到预期的行为?
我在OS X上使用Terminal.app
来运行此程序。
答案 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.
这是回车,应该将光标重新定位在该行的开头。
(顺便说一句,感谢您对代码进行评论。喜欢人们在这里做的事情:))