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.clear
– then 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
Can C++ Have Code in the Global Scope
How to Use Std::Filesystem on Gcc 8
How to Find a Search Term in Source Code
When to Make a Type Non-Movable in C++11
New to Xcode Can't Open Files in C++
Need Iterator When Using Ranged-Based for Loops
Casting Pointer to Array (Int* to Int[2])
Convert Float to Std::String in C++
Is It Legal to Use the Increment Operator in a C++ Function Call
With a Private Modifier, Why Can the Member in Other Objects Be Accessed Directly
How to Pass a Vector of Strings to Execv
Is Left-Shifting (<<) a Negative Integer Undefined Behavior in C++11
Run a Program with More Than One Source Files in Gnu C++ Compiler
Compare Double to Zero Using Epsilon
What Is the C++ Function to Raise a Number to a Power
How to Detect Ip Address Change Programmatically in Linux
Do Child Threads Exit When the Parent Thread Terminates
Should I Copy an Std::Function or How to Always Take a Reference to It