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:
- It works (GodBolt)
- 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. - This will construct an
std::strstreambuf
, which is what anstd::ostrstream
uses directly, from your buffer of chars.
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.