如何从cout回滚行?
我正在编写一个任务监控,它使用 cout 更新任务的进度。我想每行显示一个任务进度,因此我必须回滚控制台的几行。
我坚持使用“几个”,因为 \b
只完成一行的工作,但不会删除行之间的 \n
。
我尝试了 std::cout.seekp(std::cout.tellp() - str.length()); 但 tellp()
返回 -1 (失败)。
I'm coding a task monitoring, which updates tasks' progress using cout. I'd like to display one task progress per line, therefore I have to rollback several lines of the console.
I insist on "several" because \b
does the job for one line, but does not erase \n
between lines.
I tried std::cout.seekp(std::cout.tellp() - str.length());
but tellp()
returns -1 (failure).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你可以做
cout << '\r';
跳转到当前行的开头,但向上移动是特定于系统的。对于 Unix,请参阅man termcap
和man terminfo
(并搜索cursor_up
)。在 ANSI 兼容终端(例如 Unix 上可用的大多数现代终端)上,这可以向上移动:cout << “\e[A”;
。不要尝试在
cout
中查找,大多数情况下它是不可查找的(重定向到文件时除外)。正如其他答案中提到的,使用 ncurses(或 slang)库为 Unix 上的终端 I/O 提供了良好的抽象。
您可以执行
\r
+clr_eol
:std:: ,而不是填充空格(这很容易出错,因为并非每个终端都是 80 个字符宽)。计算<< “\r\e[K”<< std::flush
。You can do
cout << '\r';
to jump to the beginning of the current line, but moving upwards is system-specific. For Unix, seeman termcap
andman terminfo
(and search forcursor_up
). On ANSI-compatible terminals (such as most modern terminals available on Unix), this works to move up:cout << "\e[A";
.Don't try seeking in
cout
, it's unseekable most of the time (except when redirected to a file).As mentioned in other answers, using the ncurses (or slang) library provides a good abstraction for terminal I/O on Unix.
Instead of filling with spaces (which is error-prone, because not every terminal is 80 characters wide), you can do
\r
+clr_eol
:std::cout << "\r\e[K" << std::flush
.如果可以的话,使用输出格式化库,例如 ncurses ;这大大简化了终端操作。
Use an output formatting library such as ncurses if you can; this simplifies terminal manipulation significantly.
C 和 C++ 都没有定义类似的东西。您需要明确的终端操作。在 Unix 上,您可以使用 curses。不知道 Windows 上有什么。
Neither C nor C++ define anything like that. You need explicit terminal manipulation. On Unix you can use curses. Have no idea what's there for Windows.
我知道这是一篇旧文章,但接受的内容不包括 cout 通过管道传输到程序或文件的情况,这是我谷歌搜索的顶部。下面将处理管道和非管道标准输出,其行为略有不同。
这尚未在 Windows 上测试,但应该可以工作。它的作用是检测文件描述符 或 是否为 tty。如果是,那么如果自上次打印或换行符以来 pos 没有改变,它只会写入 '\r'。如果它不是换行符,它将查找打印后的最后一个位置。
它对于文件的行为与对于 tty 的行为不同。对于文件,如果在打印之间有某些内容输出到流,那么即使在换行符之后,它也可以覆盖部分或全部写入的内容。对于 ttys,它只是覆盖当前行开头的字符。
I know this is an old post, but the accepted doesn't cover cases where cout is piped to a program or file and this is the top of my google searches. The following will handle both piped and non-piped stdout with slightly different behavior.
This is untested on windows, but should work. What it does is detect if the file descriptor or is a tty. If it is then it just writes '\r' if the pos hasn't changed since last time it printed or a newline. If it isn't a newline, it seeks to the last place it was after it printed.
It behaves differently for files than for tty. For a file, if something outputs to the stream between prints then it can overwrite some or all of what was written even after newlines. For ttys it just overwrites the chars at the beginning of the current line.
您可以使用第一个系统(“”);因为您可以使用 \e[A (Dev-C++) 或 \u001B[A (Visual Studio)
输入图像此处描述
You can use first system(" "); for you can use \e[A (Dev-C++) or \u001B[A (Visual Studio)
enter image description here
希望它有帮助;) [它应该在 Linux 上工作。]
Hope it helps ;) [It should work on Linux.]