我应该如何向生成终端输出的 C++ 程序添加固定进度条(在 Linux 中)?

How should I add a stationary progress bar to a C++ program that produces terminal output (in Linux)?

我有一个包含文件循环的现有程序。它做各种各样的事情,提供大量的终端输出。我想要一个整体进度条,它在终端底部的同一行上保持静止,同时文件操作的所有输出都打印在它上面。我应该如何尝试做这样的事情?


编辑:所以,为了清楚起见,我正在尝试解决类似于以下内容的固有显示问题:

#include <unistd.h>
#include <iostream>
#include <string>

using namespace std;

int main(){
  for (int i = 0; i <= 100; ++i){
    std::cout << "processing file number " << i << "\n";
    string progress = "[" + string(i, '*') + string(100-i, ' ') + "]";
    cout << "\r" << progress << flush;
    usleep(10000);
  }
}

据我所知,唯一可移植的移动光标的方法是使用 \r 移动到行首。你提到你想输出进度之上的东西。幸运的是,你很幸运,因为你在 Linux 上,你可以使用终端转义码在终端中自由移动。看这个例子:

#include <unistd.h>
#include <iostream>
#include <string>

using namespace std;

int main()
{
  cout << endl;
  for (int i=0; i <= 100; ++i)
  {
    string progress = "[" + string(i, '*') + string(100-i, ' ') + "]";
    cout << "\r3[F" << i << "\n" << progress << flush;
    usleep(10000);
  }
}

在这里,我添加了在进度条上方打印进度值的功能,方法是使用 \r 移动到行的开头,并在打印前使用转义码 3[F 一行。然后,打印一行,用 \n 向下移动一行 并重新打印进度。

您可以更进一步,在打印前将光标移动到终端中的任意 X、Y 位置。为此,请在输出前使用转义码 3[Y;Xf

有关转义码的完整列表,请查看维基百科:https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes

因此,无需使用像 ncurses 这样的额外库也可以实现该行为,但如果您打算创建更像 gui 的体验,这也许正是您想要的。

修复您的尝试:

void print_progress_bar(int percentage){
  string progress = "[" + string(percentage, '*') + string(100 - percentage, ' ') + "]";
  cout << progress << "\r3[F3[F3[F" << flush;
}

int main(){
  cout << endl;
  for (int i=0; i <= 100; ++i){
    std::cout << "processing file number " << i << "\n";
    std::cout << "    doing thing to file number " << i << "\n";
    std::cout << "    doing another thing to file number " << i << "\n";
    print_progress_bar(i);
    usleep(10000);
  }
  cout << endl;
  cout << endl;
  cout << endl;
  cout << endl;
}