How to force std::stringstream operator >> to read an entire string instead of stopping at the first whitespace?
I've got a template class that stores a value read from a text file:
template <typename T>
class ValueContainer
{
protected:
  T m_value;
public:
  /* ... */
  virtual void fromString(std::string & str)
  {
    std::stringstream ss;
    ss << str;
    ss >> m_value;
  }
  /* ... */
};
I've tried setting/unsetting stream flags but it didn't help.
Clarification
The class is a container template with automatic conversion to/from type T. Strings are only one instance of the template, it must also support other types as well. That is why I want to force operator >> to mimic the behavior of std::getline.
To use stringstream class in the C++ program, we have to use the header <sstream>. For Example, the code to extract an integer from the string would be: string mystr(“2019”); int myInt; stringstream (mystr)>>myInt; Here we declare a string object with value “2019” and an int object “myInt”.
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.
Very Informally: A string is a collection of characters, a stream is a tool to manipulate moving data around. A string stream is a c++ class that lets you use a string as the source and destination of data for a stream.
strstream has been deprecated since C++98, std::stringstream and boost::iostreams::array are the recommended replacements.
As operator >> is not satisfying our requirement when T=string, we can write a specific function for [T=string] case. This may not be the correct solution. But, as a work around have mentioned.
Please correct me if it won't satisfy your requirement.
I have written a sample code as below:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
template <class T>
class Data
{
    T m_value;
    public:
    void set(const T& val);
    T& get();
};
template <class T>
void Data<T>::set(const T& val)
{
    stringstream ss;
    ss << val;
    ss >> m_value;
}
void Data<string>::set(const string& val)
{
    m_value = val;
}
template <class T>
T& Data<T>::get()
{
    return m_value;
}
int main()
{
    Data<int> d;
    d.set(10);
    cout << d.get() << endl;
    Data<float> f;
    f.set(10.33);
    cout << f.get() << endl;
    Data<string> s;
    s.set(string("This is problem"));
    cout << s.get() << endl;
}
                        Here is a solution :
std::istream & ReadIntoString (std::istream & istr, std::string & str) 
{ 
    std::istreambuf_iterator<char> it(istr), end; 
    std::copy(it, end, std::inserter(str, str.begin())); 
    return istr; 
} 
(Thanks to the original poster in C++ newsgroup)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With