How Copy from One Stringstream Object to Another in C++

how copy from one stringstream object to another in C++?

Indeed, streams are non-copyable (though they are movable).

Depending on your usage, the following works quite well:

#include <iostream>
#include <sstream>

int main()
{
std::stringstream ss1;
ss1 << "some " << 123 << " stuff" << std::flush;

std::stringstream ss2;
ss2 << ss1.rdbuf(); // copy everything inside ss1's buffer to ss2's buffer

std::cout << ss1.str() << std::endl;
std::cout << ss2.str() << std::endl;
}

Output:

some 123 stuff

some 123 stuff

can I use std::copy to copy into stringstream

You can use std::ostream_iterator.

std::stringstream ss;
std::copy(reinterpret_cast<const char*>(&tmp_time),
reinterpret_cast<const char*>(&tmp_time) + sizeof tmp_time,
std::ostream_iterator<int>(ss, " "));

You need to decide what type to use with it though. I am using int to print values as signed integers and use one space as a delimeter. You may choose something else depending on what you want to achieve.

Using std::back_inserter does not work with streams, because its purpose is to operate on containers. It creates std::back_inserter_iterator which calls push_back member function on the passed container. It also assumes that Container has member types value_type, const_reference and others (you check how they are used here).

Here an example: iterator returned by std::back_inserter has operator= defined like this:

back_insert_iterator<Container> &operator=(typename Container::value_type &&value);

So because std::stringstream does not defined value_type, compilation fails.

C++ Stringstream - copying with rd_buf changes const object

The straightforward way is to just make the string and copy that way: sstmp.str(ss.str());

The less obvious approach is to fully utilize the fact that you can gain non-const access to the rdbuf from a const stringstream.

I made several changes so your code compiles, and updated the code to directly set the rdbuf's position, but it should do what you want, now outputting:

String: Hello
String: Hello

-

#include <sstream>
#include <iostream>

void DoSomething(const std::stringstream& ss)
{
std::stringstream sstmp;

sstmp << ss.rdbuf();
ss.rdbuf()->pubseekpos(0, std::ios_base::in);

std::cout << "String: " << sstmp.str() << "\n";
}

int main()
{
std::stringstream ss;
ss << "Hello";

DoSomething(ss);
DoSomething(ss);

return 0;
}

Does stringstream copy the string on which it is constructed?

Yes. From http://en.cppreference.com/w/cpp/io/basic_stringstream/basic_stringstream

2) Uses a copy of str as initial contents of the underlying string device. The underlying basic_stringbuf object is constructed as basic_stringbuf<Char,Traits,Allocator>(str, mode).

Partial copy of a stringstream

There is another standard library algorithm called std::copy_n that will do what you want. It takes a begin iterator and the number of elements to copy. Your program works if you change the std::copy line to:

std::copy_n(std::istream_iterator<char>(str1), 3, std::ostream_iterator<char>(str2));

Demo on Compiler Explorer

An improvement might be to use std::next instead of the seekg() to advance the first iterator to the desired offset (Thanks to Armin Montigny). That would look like:

std::copy_n(std::next(std::istream_iterator<char>(str1)), 3, std::ostream_iterator<char>(str2));

Problem with ostringstream and copy constructor

Copy constructor and copy-assignment of any stream class in C++ has been made private. That means, you cannot make copy of std::ostringstream object:

std::ostringstream ss;

std::ostringstream ss1(ss); //not allowed - copy-constructor is private
ss1=ss; //not allowed - copy-assignment is private


Related Topics



Leave a reply



Submit