concatenate stringstream in c++
Solution 1
Should be:
b << dest;
a << b.str();
stringstream::str
returns the underlying string in the stringstream
.
Solution 2
Or
a << b.rdbuf();
provided that get pointer is on the beginning of the stream to avoid allocating yet another std::string
for content.
Solution 3
More generically across iostreams:
std::istream is1, is2; // eg. (i)stringstream
std::ostream os; // eg. (o)stringstream
os << is1.rdbuf();
os << is2.rdbuf();
os << std::flush;
This works for filestreams, std::cin etc. as well as for stringstream
Solution 4
You don't need two instance of std::stringstream
. One is enough for the purpose.
std::stringstream a;
a << source << dest;
std::string s = a.str(); //get the underlying string
Solution 5
The question was "how to concatenate STREAMS", the answers explained how to concatenate the contents of the streams. Here is a class which can be used to concatenate two istreams into one istream (file ConcatStreams.h):
class ConcatStreams
: public std::streambuf {
std::streambuf* sbuf1_;
std::streambuf* sbuf2_;
char* buffer_;
int useBuf;
int bufSize;
public:
ConcatStreams(std::streambuf* sbuf1, std::streambuf* sbuf2)
: bufSize(1024), sbuf1_(sbuf1), sbuf2_(sbuf2), buffer_(new char[bufSize]), useBuf(1) {
}
ConcatStreams(const ConcatStreams& orig);
virtual ~ConcatStreams() { delete[] this->buffer_; }
int underflow() {
if (this->gptr() == this->egptr()) {
// get data into buffer_, obtaining its input from
// this->sbuf_; if necessary resize buffer
// if no more characters are available, size == 0.
std::streamsize size=0;
if(useBuf==1) {
size = this->sbuf1_->sgetn(this->buffer_, bufSize);
if(!size) { useBuf++;}
}
if(useBuf==2) {
size = this->sbuf2_->sgetn(this->buffer_, bufSize);
if(!size) { useBuf++;}
}
this->setg(this->buffer_, this->buffer_, this->buffer_ + size);
}
return this->gptr() == this->egptr()
? std::char_traits<char>::eof()
: std::char_traits<char>::to_int_type(*this->gptr());
}
};
To use it:
#include "ConcatStreams.h"
istringstream msgIn1("this is a stream.");
istringstream msgIn2("this is another stream.");
ConcatStreams cs(msgIn1.rdbuf(), msgIn2.rdbuf());
istream msgIn(&cs);
cout << "'" << msgIn.rdbuf() << "'" << endl;
Basically the class uses the streambuf's from the streams passed to it to create a new streambuf which first reads the first streambuf and then reads the second streambuf when finished with the first one.
Carlitos Overflow
Updated on August 29, 2020Comments
-
Carlitos Overflow over 3 years
How can I concatenate two stringstreams?
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <fstream> #include <sstream> #include <string> #include "types.h" int main () { char dest[1020] = "you"; char source[7] = "baby"; stringstream a,b; a << source; b << dest; a << b; /*HERE NEED CONCATENATE*/ cout << a << endl; cout << a.str() << endl; return 0; }
The output is the following in both tries:
0xbf8cfd20 baby0xbf8cfddc
The desired output is
babyyou
. -
jli over 12 yearsOf course as mentioned you don't need 2
stringstream
s in this case, however I assumed that the given example is a trivial version of some more complex use case. -
Den-Jason over 6 yearsThis will create a copy of b's string data; I think the questioner may be looking for a way to avoid doing that.
-
sehe about 6 yearsThis class is bugged (the initialization of
bufSize
comes after the use in constructingbuffer_
) and is generally unnecessarily low-level. Here's a c++17 version stackoverflow.com/a/49441066/85371