2009-07-16 8 views
7

Come forzare l'operatore std :: stringstream >> a leggere un'intera stringa invece di fermarsi al primo spazio bianco?Come forzare l'operatore std :: stringstream >> a leggere un'intera stringa?

Ho una classe template che memorizza un valore letto da un file di testo:

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

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

Ho provato a installare/disinserimento bandiere flusso, ma non ha aiutato.

Chiarificazione

La classe è un modello di contenitore con conversione automatica da/tipo Corde T. sono solo un'istanza del template, deve anche supportare altri tipi pure. Ecco perché voglio forzare l'operatore >> a imitare il comportamento di std :: getline.

+2

Non sono chiaro su quale sia il problema. Se si desidera '>>' per lavorare con la classe 'T' è necessario sovrascrivere' >> 'come ad esempio ' stringstream & operator >> (T & ricevitore) '. All'interno di questa funzione si ha accesso a 'stringstream' (tramite' this') ea 'receiver' e si può uscire da' * this' qualunque quantità di dati si desideri. Potresti spiegare il problema più chiaramente? – Ari

+0

Siamo spiacenti, è 'stringstream & operator >> (stringstream & ss, T & receiver)', naturalmente, e si accede direttamente a 'ss'. – Ari

risposta

6

Come operatore >> non è soddisfare il nostro requisito quando T = stringa, possiamo scrivere una funzione specifica per il caso [T = stringa]. Questa potrebbe non essere la soluzione corretta. Ma, come ha detto un lavoro in giro.

Per favore correggimi se non soddisferà il tuo requisito.

Ho scritto un codice di esempio, come di seguito:

#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; 
} 
+0

In realtà ho risolto il problema in questo modo, usando un modello specializzato per le stringhe. Grazie per la risposta! –

1

Non c'è un modo con operatore >> di cui sono a conoscenza, ad eccezione della scrittura del proprio aspetto (operatore >> interruzione al primo carattere per cui isspace (c, getloc()) è vero). Ma esiste una funzione getline nella stringa < > che presenta il comportamento desiderato.

+0

Ne sono a conoscenza ma ho bisogno di conversione da stringa ad altri valori e non voglio creare un contenitore separato per le stringhe. –

+0

Come ho detto, l'alternativa all'uso di getline è scrivere un facet. So cosa userò. Si noti che l'uso dei tratti consentirebbe di considerare solo il comportamento di fromString e non l'intero contenitore. – AProgrammer

2

Dove vuoi che si fermi? Se vuoi leggere un'intera riga probabilmente hai bisogno della funzione getline, se hai bisogno di un'intera stringa memorizzata nell'oggetto streamstring la tua scelta è il metodo ostringstream::str.

+0

Penso che ostringstream :: str() sia la soluzione migliore qui. – p00ya

1

Suppongo che tu stia istanziando quel modello con T = std::string. In tal caso si potrebbe usare getline:

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

Tuttavia, questo presuppone che non accetterà nul-personaggi come parti validi della stringa.

Altrimenti puoi scrivere il tuo estrattore per "T".

5

Ecco una soluzione:

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

(grazie al manifesto originale in C++ newsgroup)

+1

Se il post originale è online da qualche parte, si prega di includere un link! – lumbric