How to force std::stringstream operator >> to read an entire string?

半世苍凉 提交于 2019-11-30 04:03:36

问题


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.


回答1:


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;
}



回答2:


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)




回答3:


Where do you want it to stop? If you want to read a whole line you probably need getline function, if you need an entire string stored in the streamstring object your choise is ostringstream::str method.




回答4:


I'm assuming you're instantiating that template with T = std::string. In that case you could use getline:

getline(ss, m_value, '\0');

However, this assumes you won't accept nul-characters as valid parts of the string.

Otherwise you can write your own extractor for `T'.




回答5:


There isn't a way with operator>> that I'm aware of excepted writing your own facet (operator>> stop at first character for which isspace(c, getloc()) is true). But there is a getline function in <string> which has the behaviour you want.




回答6:


If you can use Boost then use boost::lexical_cast.



来源:https://stackoverflow.com/questions/1136359/how-to-force-stdstringstream-operator-to-read-an-entire-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!