首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >倒带std::cout返回到行首

倒带std::cout返回到行首
EN

Stack Overflow用户
提问于 2010-06-17 07:46:11
回答 4查看 33K关注 0票数 29

我正在为Mac编写一个处理大量文件的命令行工具。我想向用户展示正在处理的当前文件,但不希望大量文件污染终端窗口。

相反,我想使用一行来输出文件路径,然后在下一个文件中重用该行。是否有要输出到std::cout的字符(或其他代码)来完成此操作?

另外,如果我想将此工具重新定位到Windows,那么这两个平台的解决方案是否相同?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-06-17 07:50:00

"\r“应该适用于windows和Mac OS X。

类似于:

代码语言:javascript
复制
std::cout << "will not see this\rwill see this" << std::flush;
std::cout << std::endl; // all done
票数 31
EN

Stack Overflow用户

发布于 2010-06-17 07:58:23

我不能访问mac,但从纯控制台的角度来看,这在很大程度上取决于它如何处理回车符和换行符。如果您可以从字面上将其中一个发送到控制台,那么您只需要发送一个回车即可。

我很确定Mac对待回车符和换行符的方式不同于*nix & windows。

如果您正在寻找就地更新(例如,覆盖当前行),我建议您查看curses库。这应该提供一种独立于平台的方式来做你想要做的事情。(因为,即使使用标准的C++,也不存在与平台无关的方式来实现您所要求的内容)。

票数 2
EN

Stack Overflow用户

发布于 2020-05-16 05:29:22

正如Nathan Ernst的回答所说,如果你想要一种健壮、恰当的方式来做到这一点,那就使用咒语--特别是ncurses

如果你想要一种低效的黑客方式,那就继续...

用于Linux、UNIX、MacOS、Windows等的命令行终端倾向于支持一小部分基本ASCII码控制字符,包括十进制字符13 -称为回车符,encoded in C++称为'\r‘,或者等效于八进制的'\015’或十六进制的'\x0D‘-指示终端返回到行首。

你通常想做的是..。

代码语言:javascript
复制
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会为此进行检查)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3057977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档