Rewinding Std::Cout to Go Back to the Beginning of a Line

Rewinding std::cout to go back to the beginning of a line

"\r" should work for both windows and Mac OS X.

Something like:

std::cout << "will not see this\rwill see this" << std::flush;
std::cout << std::endl; // all done

How to bring std::cout output back to the top after a new line

You can use SetConsoleCursorPosition to set the cursor location back to the top left after doing the clear.

There are also ANSI escape codes (similar to the one you use to clear the screen) that would allow you to reposition the cursor.

"\033[r;cH"

replacing r with the row and c the column to move to. They are 1-based, and default to the top left, so you can use "\033[1;1H" or just "\033[H"

Writing \r with std::cout to file saves previously overwritten lines

There is none. Terminals are not standardized in any way. Just as a file they take a stream of bytes, but they can react differently to the input you give them.

I.e. some are able to color using escape syntax. It just happens, that a terminal you are using treats \r to go back to beginning of the line and start over writing. For the file output it's just a byte to write with out any special meaning. You are not even guaranteed that \r will reset line on every terminal you run it. It is system depended.

My best advice it to decouple your UI and your log. Those are generally a different things. You don't have to put the same information into the file and the screen.

To be able to make the file stream behaviour coherent with terminal, would require to write custom fstream buffer, which would recognize \r and seek-back to last \n. It does not sound too reasonable.

How to rollback lines from cout?

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.

Returning to beginning of file after getline

Since you have reached (and attempted to read past) the end of the file, the eof and fail flags will be set. You need to clear them using ifile.clearthen try seeking:

ifile.clear();
ifile.seekg(0);

Return to begining of stream after iterating over it in C++

Clear the istream of error bits and seek back to the beginning of the file. Whether this is the optimal approach to what you want to do is another question depending on what your goal really is.

int main(int argc, char *argv[])
{
ifstream file("file.txt");

int n = count(istreambuf_iterator<char>(file), istreambuf_iterator<char>(), '\n') + 1;

file.clear();
file.seekg(0);

string row;

while (file >> row)
cout << row << endl;

return (0);
}

Printing on same line in c++

cout << "\r" << string << endl;

endl moves the cursor to the next line. Try replacing it with std::flush which just ensures output's sent towards the terminal. (You should also #include <iomanip> and use std::setw(2) / std::setfill('0') to ensure the text you display is constant width, otherwise say the time moves from:

23:59:59

to

0:0:0

The trailing ":59" from the earlier time is not currently being overwritten or cleared (you could write a few spaces or send a clear-to-end-of-line character sequence if your terminal has one, but fixed-width makes more sense).

So ultimately:

std::cout << '\r'
<< std::setw(2) << std::setfill('0') << h << ':'
<< std::setw(2) << m << ':'
<< std::setw(2) << s << std::flush;

Rewind stream pointer to the line back

Once you've read the line, it's too late. You can't go back to a
position you haven't memorized. If you need this, the only solution is
to call finput.gtell() before the getline, and then seek to what it
returned.



Related Topics



Leave a reply



Submit