How to rollback lines from cout?

倾然丶 夕夏残阳落幕 提交于 2019-11-28 07:02:44

You can do cout << '\r'; to jump to the beginning of the current line, but moving upwards is system-specific. For Unix, see man termcap and man terminfo (and search for cursor_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.

Use an output formatting library such as ncurses if you can; this simplifies terminal manipulation significantly.

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.

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.

#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;
    }
);

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.

Hope it helps ;) [It should work on Linux.]

// "\e[0K" Clear line from cursor to the end
cout << "\e[A\r\e[0K"<<what_you_want<<endl;
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!