简体   繁体   English

如何强制std :: stringstream operator >>读取整个字符串?

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

How to force std::stringstream operator >> to read an entire string instead of stopping at the first whitespace? 如何强制std :: stringstream operator >>读取整个字符串而不是在第一个空格处停止?

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. 该类是一个容器模板,可以自动转换为T类型。字符串只是模板的一个实例,它也必须支持其他类型。 That is why I want to force operator >> to mimic the behavior of std::getline. 这就是为什么我想强制operator >>模仿std :: getline的行为。

As operator >> is not satisfying our requirement when T=string, we can write a specific function for [T=string] case. 当T = string时,当运算符>>不满足我们的要求时,我们可以为[T = string]情况编写一个特定的函数。 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) (感谢C ++新闻组中的原创海报)

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. 如果你想读取整行你可能需要getline函数,如果你需要存储在streamstring对象中的整个字符串,你的选择是ostringstream :: str方法。

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). 没有办法使用运算符>>我知道除了编写自己的方面(运算符>>在第一个字符处停止,其中isspace(c,getloc())为真)。 But there is a getline function in <string> which has the behaviour you want. 但是<string>中有一个getline函数,它具有你想要的行为。

I'm assuming you're instantiating that template with T = std::string . 我假设您使用T = std::string实例化该模板。 In that case you could use getline: 在这种情况下,您可以使用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'. 否则你可以为`T'编写自己的提取器。

如果你可以使用Boost,那么使用boost :: lexical_cast

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM