Zach Starnes
Zach Starnes

Reputation: 3198

Printing on same line in c++

I am trying to write the time on the same line instead of it stacking the outputs. I can not seem to get it to work though.

Here is what I have: I thought the "\r" would make it reprint on the same line, but this doesn't work. And I also tried printf("\r"); and that didn't work either.

Can anyone help me figure out how to get this to work?

void countdown(int time)
{
    int h = (time / 3600);
    int m = (time / 60) - (h * 60);
    int s = time % 60;

    std::stringstream ss;
    ss << h << ":" << m << ":" << s;
    std::string string = ss.str();

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

Upvotes: 16

Views: 83048

Answers (4)

knoxgon
knoxgon

Reputation: 1243

I want to provide some useful information first.

You are inserting std::endl which prints next string on the next line.

std::endl is a newline \n followed by std::flush

The following newline \n and std::flush is equivalent to std::endl.

std::cout << printFunction() << '\n' << std::flush;

is just like

std::cout << printFunction() << std::endl;

Now removing std::endl will print the string in the same line.

cout << "\r" << string;

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 173044

try this:

cout << "\r" << string;

endl inserts a new-line character and flushes the stream.

Upvotes: 5

michaeltang
michaeltang

Reputation: 2898

endl inserts a new-line character and flushes the stream.

cout << "\r" << string ; //works

Upvotes: 3

Tony Delroy
Tony Delroy

Reputation: 106246

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;

Upvotes: 24

Related Questions