string – Center text in fixed-width field with stream manipulators in C++
string – Center text in fixed-width field with stream manipulators in C++
In C++20 youll be able to use std::format
to do this:
outputStream << std::format(|{:^10}|{:^10}|{:^9}|n,
Table, Column, Header);
Output:
| Table | Column | Header |
In the meantime you can use the {fmt} library, std::format
is based on. {fmt} also provides the print
function that makes this even easier and more efficient (godbolt):
fmt::print(|{:^10}|{:^10}|{:^9}|n, Table, Column, Header);
Disclaimer: Im the author of {fmt} and C++20 std::format
.
Heres a helper class that accomplish what you want:
#include <string>
#include <iostream>
#include <iomanip>
template<typename charT, typename traits = std::char_traits<charT> >
class center_helper {
std::basic_string<charT, traits> str_;
public:
center_helper(std::basic_string<charT, traits> str) : str_(str) {}
template<typename a, typename b>
friend std::basic_ostream<a, b>& operator<<(std::basic_ostream<a, b>& s, const center_helper<a, b>& c);
};
template<typename charT, typename traits = std::char_traits<charT> >
center_helper<charT, traits> centered(std::basic_string<charT, traits> str) {
return center_helper<charT, traits>(str);
}
// redeclare for std::string directly so we can support anything that implicitly converts to std::string
center_helper<std::string::value_type, std::string::traits_type> centered(const std::string& str) {
return center_helper<std::string::value_type, std::string::traits_type>(str);
}
template<typename charT, typename traits>
std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& s, const center_helper<charT, traits>& c) {
std::streamsize w = s.width();
if (w > c.str_.length()) {
std::streamsize left = (w + c.str_.length()) / 2;
s.width(left);
s << c.str_;
s.width(w - left);
s << ;
} else {
s << c.str_;
}
return s;
}
Its used simply by calling centered(String)
, like so:
int main(int argc, char *argv[]) {
std::cout << | << std::setw(10) << centered(Table)
<< | << std::setw(10) << centered(Column)
<< | << std::setw(9) << centered(Header) << |
<< std::endl;
}
string – Center text in fixed-width field with stream manipulators in C++
There is no std::center
manipulator. I am afraid you have to do it yourself. You could write a helper function to calculate the spaces given the width and the string, to reduce the efforts.
Heres a sample of what a helper function might look like. It needs some work to make it more efficient, etc.
string helper(int width, const string& str) {
int len = str.length();
if(width < len) { return str; }
int diff = width - len;
int pad1 = diff/2;
int pad2 = diff - pad1;
return string(pad1, ) + str + string(pad2, );
}