1

I need an output on the same line, like this:

std::cout << "\rIt's " << leisure << " time!";

I want to make sure I do not see stuff like time!e! at the end of the line if the next value of leisure is shorter. \t does not overwrite the symbols (if run from cmd), so I still see time!e!. \033[0K is a VT 100 escape sequence and is not supported by Windows NT. What is the best way to solve the problem and make it as crossplatform as possible?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Kaiyakha
  • 1,463
  • 1
  • 6
  • 19
  • 2
    Try adding trailing spaces after the ! – cup May 22 '22 at 21:20
  • 1
    Which version of Windows NT are you talking about? For example, Windows 10 does support [Console Virtual Terminal Sequences](https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences). – heap underrun May 22 '22 at 21:22
  • @cup the dumbest but honestly for now it seems the most crossplatform solution – Kaiyakha May 22 '22 at 21:25
  • @heapunderrun I have win 10 but enabling the option you've offered seems a complicated procedure – Kaiyakha May 22 '22 at 21:32
  • Standard C++ I/O streams do not support what you are asking for. For more complex output, use a 3rd party ncurses library instead. – Remy Lebeau May 23 '22 at 04:07

1 Answers1

0

I wanted to avoid additional coding for a single line terminator, but since there is seemingly no other solution, I resorted to Console Virtual Terminal Sequences as suggested in the comments:

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <string>


static const bool enable_VT_mode(void) {
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hOut == INVALID_HANDLE_VALUE) return false;

    DWORD dwMode = 0;
    if (!GetConsoleMode(hOut, &dwMode)) return false;

    dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    if (!SetConsoleMode(hOut, dwMode)) return false;

    return true;
}


const std::string get_terminator(void) noexcept {
    if (enable_VT_mode()) return "\x1b[0K";
    else return "                        ";
}

Then go like this:

static const std::string terminator = get_terminator();

std::cout << "\rIt's " << leisure << " time!" << terminator;

As suggested, I added WIN32_LEAN_AND_MEAN to exclude unnecessary stuff from windows.h

Kaiyakha
  • 1,463
  • 1
  • 6
  • 19
  • 1
    You might want to add #define WIN32_LEAN_AND_MEAN before See https://stackoverflow.com/a/11040230/2041317 – cup May 23 '22 at 10:44