I started learning c++ and what seemed to be a piece of cake task turned out to be a big headache.
I noticed than a unicode symbol in my formatting eats a piece of column width. Even more when I was preparing a minimal reproducible example for this question I noted that the more symbols I add, the more width is eaten.
#include <iostream>
#include <format>
int main (int argc, char *argv[]) {
std::cout << std::format("|{0:30}|{1:30}|\n", "Constant", "Approximate value");
std::cout << std::format("|{0:30}|{1:30.5f}|\n", "p", std::numbers::pi);
std::cout << std::format("|{0:30}|{1:30.5f}|\n", "π", std::numbers::pi);
std::cout << std::format("|{0:30}|{1:30.5f}|\n", "ππ", std::numbers::pi);
std::cout << std::format("|{0:30}|{1:30.5f}|\n", "πππ", std::numbers::pi);
return 0;
}
Resulting in
|Constant |Approximate value |
|p | 3.14159|
|π | 3.14159|
|ππ | 3.14159|
|πππ | 3.14159|
I would really appreciate your explanation of what the mechanism is behind this phenomenon. BTW please find the interactive example here: https://godbolt.org/z/s9Mf7KPYz
EDIT: I just double checked, and I'm actually wrong. Since the argument is neither a floating point number nor an integer, the left alignment should be the default.
This had to be a compiler bug since simply changing the compiler version gave the right output.
{0:30}
means that the variable 0
will be followed by 30
spaces.
For the separator (|
) to be alined you can use {0:<30}
:
std::format("|{0:<30}|{1:30.5f}|\n", "p", std::numbers::pi)
To align the variable 0
left and add padding so that the length of the line is 30
. (cppreference)
Live on Compiler Explorer.