在C/C++中,如何编辑stdout中的某个'coordinate'?
In C/C++, how do you edit a certain 'coordinate' in stdout?
我最近经常使用 Vim,我想知道程序是如何设法改变终端中某些位置的字符的。例如,当使用:rc 时,它将光标下的字符替换为 c.
我也见过用 Homebrew 做的类似事情,它会在屏幕上打印一个进度条并在必要时更新它。
C/C++ 是如何做到的?
在 C++ 中没有执行此操作的标准方法。
用OS个依赖库完成,比如curses and similar libraries (ncurses) in the Unix/Linux world. Some of these libraries have been ported on across platforms (example: PDCurses)
对于非常简单的东西,例如进度条或计数器,只要您保持在一行上,就有在输出中使用“\r”(carriage return) 的技巧,将光标回到当前行的开头。示例:
for (int i = 0; i < 100; i++) {
cout << "\rProgress: " << setw(3) << i;
this_thread::sleep_for(chrono::milliseconds(100));
}
我不确定是否完全理解您的意思,但是通过创建一个包含 100 个 char 类型元素的数组,您可以修改数组的任何位置并使用 std:cout 循环它以在控制台上显示它。
也许可以更好地定义 50 个字符的数组以减少打印结果的大小。
比如你要在1%的进程中打印一个progessbar,你应该打印:
Char progressbar[100] = {'X','','','','','','','','',........}
如前所述,这与 stdout
或 cout
提供的任何 C/C++ 标准操作无关(除了将必要的控制字符写入屏幕)。
控制 ASCII 终端的屏幕光标完全取决于所使用的特定终端程序的实现,除了 very narrow set of control characters 之外,还没有建立标准。
对于 windows CMD shell,有像 ncurses for a broader variety of linux terminal implementations, or PDcurses 这样的库。
当然,使用 ncurses
或类似的库是一个很好的答案。另一种方法是使用 ANSI Escape Codes 来控制某些终端仿真器中的光标(但不是 Windows 命令 shell)。例如,此代码以多种颜色打印一行,然后将光标移动到 2,2(坐标以 1 为基础,1,1 为左上角)并以红色打印单词 "red"。
#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';
}
我最近经常使用 Vim,我想知道程序是如何设法改变终端中某些位置的字符的。例如,当使用:rc 时,它将光标下的字符替换为 c.
我也见过用 Homebrew 做的类似事情,它会在屏幕上打印一个进度条并在必要时更新它。
C/C++ 是如何做到的?
在 C++ 中没有执行此操作的标准方法。
用OS个依赖库完成,比如curses and similar libraries (ncurses) in the Unix/Linux world. Some of these libraries have been ported on across platforms (example: PDCurses)
对于非常简单的东西,例如进度条或计数器,只要您保持在一行上,就有在输出中使用“\r”(carriage return) 的技巧,将光标回到当前行的开头。示例:
for (int i = 0; i < 100; i++) {
cout << "\rProgress: " << setw(3) << i;
this_thread::sleep_for(chrono::milliseconds(100));
}
我不确定是否完全理解您的意思,但是通过创建一个包含 100 个 char 类型元素的数组,您可以修改数组的任何位置并使用 std:cout 循环它以在控制台上显示它。 也许可以更好地定义 50 个字符的数组以减少打印结果的大小。
比如你要在1%的进程中打印一个progessbar,你应该打印:
Char progressbar[100] = {'X','','','','','','','','',........}
如前所述,这与 stdout
或 cout
提供的任何 C/C++ 标准操作无关(除了将必要的控制字符写入屏幕)。
控制 ASCII 终端的屏幕光标完全取决于所使用的特定终端程序的实现,除了 very narrow set of control characters 之外,还没有建立标准。
对于 windows CMD shell,有像 ncurses for a broader variety of linux terminal implementations, or PDcurses 这样的库。
当然,使用 ncurses
或类似的库是一个很好的答案。另一种方法是使用 ANSI Escape Codes 来控制某些终端仿真器中的光标(但不是 Windows 命令 shell)。例如,此代码以多种颜色打印一行,然后将光标移动到 2,2(坐标以 1 为基础,1,1 为左上角)并以红色打印单词 "red"。
#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';
}