我正在为Mac编写一个处理大量文件的命令行工具。我想向用户展示正在处理的当前文件,但不希望大量文件污染终端窗口。
相反,我想使用一行来输出文件路径,然后在下一个文件中重用该行。是否有要输出到std::cout
的字符(或其他代码)来完成此操作?
另外,如果我想将此工具重新定位到Windows,那么这两个平台的解决方案是否相同?
发布于 2010-06-17 07:50:00
"\r“应该适用于windows和Mac OS X。
类似于:
std::cout << "will not see this\rwill see this" << std::flush;
std::cout << std::endl; // all done
发布于 2020-05-16 05:29:22
正如Nathan Ernst的回答所说,如果你想要一种健壮、恰当的方式来做到这一点,那就使用咒语--特别是ncurses。
如果你想要一种低效的黑客方式,那就继续...
用于Linux、UNIX、MacOS、Windows等的命令行终端倾向于支持一小部分基本ASCII码控制字符,包括十进制字符13 -称为回车符,encoded in C++称为'\r‘,或者等效于八进制的'\015’或十六进制的'\x0D‘-指示终端返回到行首。
你通常想做的是..。
int line_width = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 80;
std::string spaces{line_width - 1, ' '};
for (const auto& filename : filenames) {
std::cout << '\r' << spaces << '\r' << filename << std::flush;
process_file(filename);
}
std::cout << std::endl; // move past last filename...
这在写入下一个文件名之前使用一个空格字符串来覆盖旧的文件名,所以如果您有一个较短的文件名,您就看不到较早的较长文件名的尾随字符。
std::flush
确保C++程序在开始处理文件之前调用OS write()
函数将文本发送到终端。否则,更新所需的文本- \r
、空格、\r
和文件名-将被附加到缓冲区,并仅在缓冲区已满时才写入操作系统,例如4k块,因此显示的文件名将落后于正在处理的实际文件数十个文件。此外,假设缓冲区为4k - 4096字节-在某一时刻,您有4080个字节的缓冲区,然后输出下一个文件名的文本:您将以\r
和15个空格填充缓冲区结束,当自动刷新时,它将在屏幕上擦除行上的前15个字符,并留下前一个文件名的其余部分(如果它超过15个字符),然后等待缓冲区再次满,然后再更新屏幕(仍然是随意的)。
最后的std::endl
只是将光标从您打印文件名的行移到前面,这样您就可以写下"all done",或者干脆离开main()
,让shell提示符显示在整齐的行上,而不是可能覆盖上一个文件名的一部分(像zsh这样的很棒的shell会为此进行检查)。
发布于 2014-11-13 21:34:12
std::cout解释器"\r“返回到本行,如果您不想每次都添加"<< endl”,请使用"\n“
std::cout << "this will work!\nSee... a new line!" << std::endl;
https://stackoverflow.com/questions/3057977
复制相似问题