C++ string formatting like Python "{}".format

Viewed 23920

I am looking for a quick and neat way to print in a nice table format with cells being aligned properly.

Is there a convenient way in c++ to create strings of substrings with certain length like python format

"{:10}".format("some_string")
6 Answers

In C++20 you'll be able to use std::format which brings Python-like formatting to C++:

auto s = std::format("{:10}", "some_string");

Until then you can use the open-source {fmt} formatting library, std::format is based on.

Disclaimer: I'm the author of {fmt} and C++20 std::format.

If you cannot use fmt as mentioned above the best way would be to use a wrapper class for formatting. Here is what I have done once:

#include <iomanip>
#include <iostream>

class format_guard {
  std::ostream& _os;
  std::ios::fmtflags _f;

public:
  format_guard(std::ostream& os = std::cout) : _os(os), _f(os.flags()) {}
  ~format_guard() { _os.flags(_f); }
};

template <typename T>
struct table_entry {
  const T& entry;
  int width;
  table_entry(const T& entry_, int width_)
      : entry(entry_), width(static_cast<int>(width_)) {}
};

template <typename T>
std::ostream& operator<<(std::ostream& os, const table_entry<T>& e) {
  format_guard fg(os);
  return os << std::setw(e.width) << std::right << e.entry; 
}

And then you would use it as std::cout << table_entry("some_string", 10). You can adapt table_entry to your needs. If you don't have class template argument deduction you could implement a make_table_entry function for template type deduction.

The format_guard is needed since some formatting options on std::ostream are sticky.

Related