kevinjfq
kevinjfq

Reputation: 11

Using C++ {fmt}, is there a cleaner way to append a sequence of data to a string than using std::ostringstream?

The {fmt} library provides a clean, readable and fast way to format string data in C++, but I cannot find a clean and readable way to use it to append a sequence of data to a string.

After much googling, I've come up with a working solution, but it is much more verbose than using the typical approach of std streams and chevrons. I can't any/many examples of this using {fmt}, so I'm hoping some expert out there knows a neater way of doing this.

 // Here is an {fmt} version of dump_line.  I don't like it.  using 'cout' seems cleaner and simpler.
virtual void dump_line( const char* msg, uint8_t* dataline )
{
  fmt::memory_buffer out;
  format_to(out, "{} :", msg);
  for( int jj=0; jj<m_cacheStore.p_LineSize; jj++) {
    format_to(out, " [{}]={}", jj, (int)dataline[jj] );
  }
  fmt::print("{}\n",fmt::to_string(out) );
}

// Here is the typical approach using cout and chevrons.
// Nice and simple. 
virtual void dump_line( const char* msg, uint8_t* dataline )
{
  cout << msg << " : " ;
  for( int jj=0; jj<m_cacheStore.p_LineSize; jj++)
    cout << " [" << jj << "]=" << (int)dataline[jj];
  cout<<endl;
}

I'm just dumping an array of ints to stdout to look like this: [0]=2 [1]=0 [2]=0 [3]=0 [4]=1 [5]=0 [6]=0 [7]=0

Upvotes: 1

Views: 3470

Answers (1)

vitaut
vitaut

Reputation: 55665

You can write to the output stream directly without an intermediate buffer:

virtual void dump_line(const char* msg, uint8_t* dataline) {
  fmt::print("{} :", msg);
  for (int jj=0; jj<m_cacheStore.p_LineSize; jj++) {
    fmt::print(" [{}]={}", jj, dataline[jj]);
  }
  fmt::print("\n");
}

Note that you don't need to cast dataline[jj] to int, because unlike iostreams, {fmt} correctly handles uint8_t.

If you want to build a string you can either write to a memory_buffer or pass back_insert_iterator to format_to.

Upvotes: 1

Related Questions