Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

non-copying istringstream

So istringstream copies the contents of a string when initialised, e.g

string moo("one two three four");
istringstream iss(moo.c_str());

I was wondering if there's a way to make std::istringstream use the given c_str as its buffer without copying things. This way, it won't have to copy large bits of memory before passing the std::istringstream& to functions that take istream& as an argument.

What I've been trying to do is convert some functions which only take std::ifstream& arguments (they're mostly parsers) into taking istream& as well. Would I have to make my own istream subclass for this?

like image 221
kamziro Avatar asked Jun 26 '10 05:06

kamziro


People also ask

What is an Istringstream?

The std::istringstream is a string class object which is used to stream the string into different variables and similarly files can be stream into strings. Objects of this class use a string buffer that contains a sequence of characters. This sequence of characters can be accessed as a string object.

Why would you use the Istringstream class?

Stringstream class is used for insertion and extraction of data to/from the string objects. It acts as a stream for the string object. The stringstream class is similar to cin and cout streams except that it doesn't have an input-output channel.

How does Istringstream work in C++?

The StringStream class in C++ is derived from the iostream class. Similar to other stream-based classes, StringStream in C++ allows performing insertion, extraction, and other operations. It is commonly used in parsing inputs and converting strings to numbers, and vice-versa.


2 Answers

Using istringstream is not a satisfactory solution, because this copies the entire buffer.

A previous answer suggests the deprecated istrstream, but as this generates warnings and may be removed in future, a better solution is to use boost::iostreams:

boost::iostreams::stream<boost::iostreams::array_source> stream(moo.c_str(), moo.size());

This avoids copying the buffer in the same way istrstream did, and saves you having to write your own stream class.

like image 200
Riot Avatar answered Nov 08 '22 00:11

Riot


It's fairly trivial to write a basic std::streambuf class that reads from a given memory area. You can then construct an istream from this and read from that.

initializing a C++ std::istringstream from an in memory buffer?

Note that the lifetime of the buffer pointed to be c_str() is very limited, though, and there's no guarantee that a call to c_str() want cause some copying although I don't know of any implementations where it does.

like image 5
CB Bailey Avatar answered Nov 08 '22 00:11

CB Bailey