Как заставить оператор std :: stringstream >> прочитать всю строку? - PullRequest
7 голосов
/ 16 июля 2009

Как заставить оператор std :: stringstream >> прочитать всю строку вместо остановки на первом пробеле?

У меня есть шаблон класса, который хранит значение, прочитанное из текстового файла:

template <typename T>
class ValueContainer
{
protected:
  T m_value;

public:
  /* ... */
  virtual void fromString(std::string & str)
  {
    std::stringstream ss;
    ss << str;
    ss >> m_value;
  }
  /* ... */
};

Я пытался установить / сбросить флаги потоков, но это не помогло.

Разъяснение

Класс представляет собой контейнерный шаблон с автоматическим преобразованием в / из типа T. Строки являются только одним экземпляром шаблона, он также должен поддерживать другие типы. Вот почему я хочу заставить operator >> имитировать поведение std :: getline.

Ответы [ 6 ]

6 голосов
/ 16 июля 2009

Поскольку оператор >> не удовлетворяет нашему требованию, когда T = строка, мы можем написать специальную функцию для случая [T = string] Это может быть не правильным решением. Но, как обойти уже упоминал.

Пожалуйста, исправьте меня, если он не удовлетворит ваше требование.

Я написал пример кода, как показано ниже:

#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;
}
5 голосов
/ 16 июля 2009

Вот решение:

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

(благодаря оригинальному постеру в группе новостей C ++)

2 голосов
/ 16 июля 2009

Где вы хотите, чтобы это остановилось? Если вы хотите прочитать целую строку, вам, вероятно, нужна функция getline , если вам нужна вся строка, хранящаяся в объекте streamstring, вы можете выбрать метод ostringstream :: str .

1 голос
/ 24 ноября 2011

Если вы можете использовать Boost , тогда используйте boost :: lexical_cast .

1 голос
/ 16 июля 2009

Я предполагаю, что вы создаете экземпляр этого шаблона с T = std::string. В этом случае вы можете использовать getline:

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

Однако это предполагает, что вы не примете nul-символы в качестве допустимых частей строки.

В противном случае вы можете написать свой собственный экстрактор для `T '.

1 голос
/ 16 июля 2009

С оператором >> не существует способа, при котором мне известно о том, что вы можете написать свой собственный фасет (оператор >> останавливаться на первом символе, для которого isspace (c, getloc ()) имеет значение true). Но в есть функция getline, которая имеет желаемое поведение.

...