我最近经常使用Vim,我想知道程序是如何更改终端中某些位置的字符的。例如,当使用:rc时,它将光标下的字符替换为c.
我也见过Homebrew做过类似的事情,它会在屏幕上打印进度条,并在必要时更新。
这是如何在C/C++中完成的?
在C++中没有标准的方法。
它是用依赖于操作系统的lbiraries完成的,例如Unix/Linux世界中的curses和类似库(ncurses)。其中一些库已经跨平台移植(例如:PDCurses)
对于非常简单的事情,如进度条或计数器,只要您停留在一行上,就可以在输出中使用"\r"(回车)将光标放回当前行的开头。示例:
for (int i = 0; i < 100; i++) {
cout << "rProgress: " << setw(3) << i;
this_thread::sleep_for(chrono::milliseconds(100));
}
当然,使用ncurses
或类似的库是一个不错的答案。另一种选择可能是使用ANSI转义码来控制某些终端模拟器中的光标(但不是Windows命令shell)。例如,此代码以多种颜色打印一行,然后将光标移动到2,2(坐标以1为基础,左上角为1,1),并以红色打印单词"红色"。
#include <iostream>
#include <string>
const std::string CSI{"x1b["};
const std::string BLUE{CSI + "34m"};
const std::string RED{CSI + "31m"};
const std::string RESET{CSI + "0m"};
std::ostream &curpos(int row, int col)
{
return std::cout << CSI << row << ';' << col << 'H';
}
int main()
{
std::cout << "This is " << BLUE << "blue" << RESET << " and white.n";
curpos(2,2);
std::cout << RED << "red" << RESET << 'n';
}
如前所述,这与stdout
或cout
提供的任何C/C++标准操作无关(除了将必要的控制字符写入屏幕之外)。
控制ASCII终端的屏幕光标完全取决于所用特定终端程序的实现,除了一组非常窄的控制字符外,还没有建立标准。
有一些库,比如用于更广泛的linux终端实现的ncurses,或者用于windows CMD shell的PDcurses。
我不确定是否完全理解你,但通过创建一个由100个char类型元素组成的数组,你可以修改数组的任何位置,并用std:cut循环它,以便在控制台上对其进行优化。也许可以更好地定义50个字符的数组,以恢复打印结果的大小。
例如,如果你必须在1%的过程中打印进度条,你应该打印:
Char progressbar[100] = {'X','','','','','','','','',........}