NoSenseEtAl
NoSenseEtAl

Reputation: 30058

Filling after quoted value in fmt

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

Answers (1)

vitaut
vitaut

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

Related Questions