How to flush fmt output in debug mode?

Viewed 252

I'm experimenting with fmt and I do get output from code below

#include <fmt/color.h>

int main() {
  fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
             "Hello, {}!\n", "world");
  fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
             fmt::emphasis::underline, "Hello, {}!\n", "???");
  fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
             "Hello, {}!\n", "??");
}

However it seems to happen after program exits. If I step over each line in debug mode there is no output?

Perhaps it should flush?

I tried fflush(stdout); unsuccessfuly.

The following seems to help. With it I get the prints with sleep in the middle. However still no print during debug while stepping in each line.

setbuf(stdout, NULL);

https://thomas.trocha.com/blog/qt-creator--make-stdout-work-in-application-output-view/

int main() {

    setbuf(stdout, NULL);

    fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
                   "Hello, {}!\n", "world");

    qDebug() << "1";
    QThread::msleep(2000);
    qDebug() << "2";

    fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
               fmt::emphasis::underline, "Hello, {}!\n", "???");

    QThread::msleep(2000);

    fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
               "Hello, {}!\n", "??");
}
2 Answers

fmt uses buffered output. It comes with its own buffer class.
It outputs to stdout, I'm not sure about qDebug but from the name it doesn't use stdout.
Did you remember to check the "Run in terminal" check box?
In any case: you can change the output stream used by fmt::print by passing a std::FILE* as the first argument.

fmt::print(stderr, "This is printed first");
std::cerr << "This is printed second.";
std::cout << "When this is printed is implementation defined.";
std::clog << "Unlike std::cerr and std::cin, std::clog will not flush std::cout.";

Detailed example on compiler explorer
I'm not aware of any way to flush the fmt print buffer manually. I'm looking into it.

Instead of using fmt::print, you could use fmt::format and send that to std::cout and use std::flush:

#include <fmt/color.h>
#include <iostream>

int main() {
  std::cout << fmt::format(fg(fmt::color::crimson) | fmt::emphasis::bold,
             "Hello, {}!\n", "world") << std::flush;

  std::cout << fmt::format(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
             fmt::emphasis::underline, "Hello, {}!\n", "???") << std::flush;
             
  std::cout << fmt::format(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
             "Hello, {}!\n", "??")  << std::flush;
}
Related