1

Assume I have the following code which is an infinit counter :

#include <iostream> int main() { short int counter = 0; while(true) cout << "This is a counter: " << counter++ << " and I'll keep counting!\r"; return 0; } 

When you run the code with the carriage return, it will overwrite the existing text, but at the end there will be more than one '!'. Is there away to fix this without calling clear screen to avoid flickering?

8
  • "Print" into a string, and pad it with spaces at the end to be at least as long as the previous string. Then output the string. Or, since you know that a short signed integer can't be longer than five characters (32767) you can make sure the string is always padded for the correct length. Commented Jan 6, 2021 at 13:43
  • 1
    Add several spaces after the exclamation mark. Commented Jan 6, 2021 at 13:43
  • 2
    A bit puzzled, though. How can there be a left-over exclamation mark if counter is only ever increasing? Commented Jan 6, 2021 at 13:44
  • 1
    @Dialecticus it's a short int, it will overflow and come back around from the negative Commented Jan 6, 2021 at 13:46
  • 1
    If using a VT compatible output terminal (most are), add cout << "\033[0k" << ... which is the ANSI escape to "Clear to end of line". Commented Jan 6, 2021 at 13:47

2 Answers 2

1

Continuing from the comments above, if you are outputting to a VT compatible terminal (most are), you can use ANSI Escape sequences to control clearing to end-of-line (and various other cursor movements and visibility).

A short example working with lines terminated with a carriage-return, you can use \033[K to clear to end of line. (the formal number preceding 'K' is "0K" but can be omitted due to it being the default) The other line clearing options are "1K" clear to beginning of line, and "2K" clear entire line. You can also hide and restore the cursor with similar escapes.

In your case you can handle the additional characters from previous longer lines as:

#include <iostream> #include <unistd.h> int main (void) { const char *lines[] = { "You do not ever want\r", "your favorite dog\r", "to have\r", "fleas!\r" }; int n = sizeof lines / sizeof *lines; std::cout << "\033[?25l"; /* hide cursor */ for (int i = 0; i < n; i++) { std::cout << "\033[0K" << lines[i]; /* clear to end, output line */ std::fflush (stdout); sleep (2); } std::cout << "\033[?25h\n"; /* restore cursor */ } 

Compile normally and run in your terminal. If it is VT compatible it will process the escapes so you see each line printed without any of the additional characters from the preceding line interfering with the output.

Sign up to request clarification or add additional context in comments.

Comments

1

You could first write a line of just spaces to the "maximum" expected length, itself with a \r at the end.

Alternatively, on each iteration count how many spaces you might need to pad the end of your new line to reach that maximum.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.