Reputation: 30058
I want to fill after a quoted value with C++ fmt. I know I can just make the quoting in one step and then just use fmt with one argument, but I presume that is slower and from readability perspective I would like to do it in one go. I have this solution.
but is seems a bit clunky, I am manually doing alignment computations accounting for the fact I have quotes around the value...
#include <array>
#include <string>
#include <iostream>
#include <fmt/format.h>
void write_padded(const int i,char* data) {
// note: - format_to_n will not zero termiante if out of space
// - use '^' as a fill char for visibility
auto result = fmt::format_to_n(data,7, R"("{}{:^<5})",i,'\"');
*result.out = '\0';
}
int main() {
// space for 5 digits, 2 quotes \0
std::array<char, 8> data{};
write_padded(1, data.data());
std::cout << data.data() << std::endl;
write_padded(10, data.data());
std::cout << data.data() << std::endl;
write_padded(123456789, data.data());
std::cout << data.data() << std::endl;
write_padded(54321, data.data());
std::cout << data.data() << std::endl;
}
This seems to work, but I would like to do this without me doing manual computation of width . and maybe also with a bit nicer format string.
note: I know integers can be longer than 5 digits and that magic numbers are bad, but even with named variables I would still need to do computations.
Upvotes: 1
Views: 233
Reputation: 55595
You can write a formatter that does quoting, for example:
#include <fmt/format.h>
struct quoted {
int value;
};
template <>
struct fmt::formatter<quoted> : formatter<string_view> {
auto format(quoted q, format_context& ctx) const {
auto buf = fmt::memory_buffer();
fmt::format_to(std::back_inserter(buf), "\"{}\"", q.value);
return formatter<string_view>::format({buf.data(), buf.size()}, ctx);
}
};
int main() {
fmt::print("{:^<7}\n", quoted{1});
}
This prints
"1"^^^^
https://godbolt.org/z/Gs5qPTT13
Upvotes: 3