Home > Mobile >  Can I use an std::ostream to print into a given buffer?
Can I use an std::ostream to print into a given buffer?

Time:06-04

I have a given buffer of characters (maybe even the buffer backing an std::string, but never mind that). I want to print into that buffer using an std::ostream, i.e. I want to be able to write:

span<char> my_buffer = get_buffer();
auto my_os = /* magic */;
static_assert(
   std::is_base_of<std::basic_ostream<char>,decltype(my_os)>::value,
   "magic failed");
my_os << "hello" << ',' << 123 << '\0';
std::cout << my_buffer << '\n';

and get:

hello,123

on the standard output.

Note: C 11 if possible, and please mention the language standard you're using. (And yes, I know C 11 doesn't have spans.)

CodePudding user response:

(Thank @BoP and @T.C. for the two parts of this solution)

This can be done... if you're willing to use a deprecated C construct: std:ostrstream.

#include <strstream>
#include <iostream>

int main() {
    const size_t n = 20;
    char my_buffer[n];
    std::ostrstream my_os(my_buffer, n);
    my_os << "hello" << ',' << 123 << '\0';
    std::cout << my_buffer << '\n';
}

Notes about this code:

  1. It works (GodBolt)
  2. It is valid C 98! ... of course I had to let go of std::span, auto type inference etc. It's also valid C 11 and later standards.
  3. This will construct an std::strstreambuf, which is what an std::ostrstream uses directly, from your buffer of chars.

(see this on GodBolt)

Unfortunately, with the deprecation of std::ostrstream, we were left with no fully-valid alternative up to, and including, C 20. You would need to implement a custom std::basic_streambuf, and assign it to an std::ostream. :-(

But in C 23 - you are luck! The standard library does offer exactly what you asked for: std::spanstream: A std::ostream backed by a span of char's which it is given at construction.

  • Related