15

我正在编写一个任务监控,它使用 cout 更新任务的进度。我想每行显示一个任务进度,因此我必须回滚控制台的几行。

我坚持“几个”,因为\b只为一行完成这项工作,但不会\n在两行之间擦除。

我试过std::cout.seekp(std::cout.tellp() - str.length());tellp()返回-1(失败)。

4

6 回答 6

25

您可以cout << '\r';跳到当前行的开头,但向上移动是系统特定的。对于 Unix,请参见man termcapman terminfo(并搜索cursor_up)。在 ANSI 兼容的终端(例如 Unix 上可用的大多数现代终端)上,这可以向上移动:cout << "\e[A";.

不要尝试在 中搜索cout,大多数时候它是不可搜索的(重定向到文件时除外)。

正如其他答案中提到的,使用ncurses(或slang)库为 Unix 上的终端 I/O 提供了一个很好的抽象。

\r您可以使用+ clr_eol:代替填充空格(这很容易出错,因为并非每个终端都是 80 个字符宽)std::cout << "\r\e[K" << std::flush

于 2010-07-18T20:17:26.983 回答
8

如果可以,请使用输出格式库,例如ncurses ;这大大简化了终端操作。

于 2010-07-18T20:15:11.793 回答
5

C 和 C++ 都没有定义类似的东西。您需要明确的终端操作。在 Unix 上,您可以使用curses。不知道 Windows 有什么。

于 2010-07-18T20:16:59.950 回答
2

我知道这是一个旧帖子,但接受的不包括 cout 被管道传输到程序或文件的情况,这是我的谷歌搜索的顶部。以下将处理管道和非管道标准输出,其行为略有不同。

#include <iostream>
#include <functional>
#include <stdio.h>

#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#define _isatty isatty
#define _fileno fileno
#endif

const std::function<void(const size_t&)> progress_printer(_isatty(_fileno(stdout)) == 1 ?
    [](const size_t& i) {
        std::cout << "\rNumber " << i << std::flush;
    } :
    [](const size_t& i) {
        static std::ios::off_type last(-1);
        if(last != -1)
            std::cout.seekp(last, std::ios::beg);
        last = std::cout.tellp();
        std::cout << "Number " << i << std::endl;
    }
);

这在 Windows 上未经测试,但应该可以工作。它的作用是检测文件描述符是否为 tty。如果是,那么如果自上次打印后 pos 没有更改或换行,它只会写入 '\r'。如果它不是换行符,它会寻找打印后的最后一个位置。

它对文件的行为与对 tty 的行为不同。对于一个文件,如果某些内容在打印之间输出到流,那么即使在换行符之后,它也可以覆盖部分或全部写入的内容。对于 ttys,它只是覆盖当前行开头的字符。

于 2016-07-27T17:05:52.783 回答
1

您可以使用第一个系统(“”);因为您可以使用 \e[A (Dev-C++) 或 \u001B[A (Visual Studio)

#include <iostream>
using namespace std;
int main()
{
    system(" ");
    string Input;
    do
    {
        cout << "[#][\e[s";
        cin >> Input;
        cout << "[\e[u" << Input << "]"<<endl;

    } while (2==2);
    return 0;
}

在此处输入图像描述

于 2019-10-06T01:28:13.493 回答
0

希望它有所帮助;) [它应该在 Linux 上工作。]

// "\e[0K" Clear line from cursor to the end
cout << "\e[A\r\e[0K"<<what_you_want<<endl;
于 2018-05-31T02:06:29.177 回答