2010-12-28 9 views
12

Nel mio codice c'è un ciclo che aggiunge sth come quel "numero" a stringstream. Quando termina, ho bisogno di estrarre ',' aggiungere '}' e aggiungere '{' se il ciclo deve essere ripetuto.rimuove char da stringstream e aggiunge alcuni dati

Ho pensato di poter usare ignore() per rimuovere ',' ma non ha funzionato. Sai come posso fare ciò che descrivo?

esempio:

douCoh << '{'; 
for(unsigned int i=0;i<dataSize;i++) 
    if(v[i].test) douCoh << i+1 << ','; 
douCoh.get(); douCoh << '}'; 
+1

Aggiungi qualche esempio per illustrare il tuo punto. –

risposta

22

È possibile estrarre la stringa (con il membro str()), rimuovere l'ultimo carattere con std::string::erase e quindi reimpostare la nuova stringa come buffer su std::ostringstream.

Tuttavia, una soluzione migliore potrebbe essere quella di non inserire il superfluo ',' in primo luogo, facendo qualcosa di simile:

std::ostringstream douCoh; 
const char* separator = ""; 

douCoh << '{'; 
for (size_t i = 0; i < dataSize; ++ i) 
{ 
    if (v[i].test) 
    { 
    douCoh << separator << i + 1; 
    separator = ","; 
    } 
} 
douCoh << '}'; 
+0

Accidenti, sei stato più veloce di pochi secondi ... – RedX

+0

bello, prendilo :) –

0

Si potrebbe utilizzare std::string::erase per rimuovere l'ultimo carattere direttamente dalla stringa sottostante.

+1

Come posso ottenere la stringa sottostante? str() restituisce una copia di stringa non un riferimento, non è vero? –

+0

Sì, si ottiene una copia dei contenuti usando str(). – RedX

+1

Esiste un altro override della funzione 'std :: ostringstream :: str' che consente di modificare il buffer. Tuttavia, questa soluzione costa due copie del contenuto del buffer, che può essere coslty. –

0

Perché non solo controllare il contatore? E non inserire la ''

douCoh << '{'; 
for(unsigned int i=0;i<dataSize;i++){ 
    if(v[i].test){ 
    douCoh << i+1; 
    if(i != dataSize - 1) douCoh << ','; 
    } 
} 
/*douCoh.get();*/ douCoh << '}'; 
+0

Penso che non sia possibile controllare il contatore perché ci possono essere alcuni oggetti che non superano il test. È necessario un altro contatore (che può essere un bool), oppure è possibile utilizzare il mio trucco per cambiare la variabile di separazione. –

+0

È impossibile prevedere il valore di v [j] .test per j> i prima del codice. –

0

divertirsi con std :: copia, iteratori e tratti. È necessario presumere che i dati siano reversibili (end-1) o che l'output possa essere riavvolto. Ho scelto che era più facile riavvolgere.

#include <ostream> 
#include <algorithm> 
#include <iterator> 

namespace My 
{ 
    template<typename Iterator> 
    void print(std::ostream &out, Iterator begin, Iterator end) 
    { 
    out << '{'; 
    if (begin != end) { 
     Iterator last = end - 1; 
     if (begin != last) { 
     std::copy(begin, last, std::ostream_iterator< typename std::iterator_traits<Iterator>::value_type >(out, ", ")); 
     } 
     out << *last; 
    } 
    out << '}'; 
    } 
} 

#include <iostream> 

int main(int argc, char** argv) 
{ 
    My::print(std::cout, &argv[0], &argv[argc]); 
    std::cout << '\n'; 
} 
+0

Oppure, è necessario scrivere il ciclo completo anziché fare affidamento su std :: copy. –

+0

Penso che volesse evitare di scrivere tonnellate di codice ... –

2
stringstream douCoh; 
for(unsigned int i=0;i<dataSize;i++) 
    if(v[i].test) 
    douCoh << (douCoh.tellp()==0 ? '{' : ',') << i+1; 
douCoh << '}'; 
+0

Benvenuto in StackOverflow! Sarebbe utile se hai spiegato il tuo codice per quelli che non lo capiscono. – ajacian81

+0

+1. Questo è il mio preferito. – refi64

0

ho trovato in questo modo con il metodo pop_back() di stringa dal C++ 11. Probabilmente non sono tanto buone quanto quelle più intelligenti sopra, ma utili in casi molto più complicati e/o per persone pigre.

douCoh << '{'; 
for(unsigned int i=0;i<dataSize;i++) 
    if(v[i].test) douCoh << i+1 << ','; 

string foo(douCoh.str()); 
foo.pop_back(); 
douCoh.str(foo); 
douCoh.seekp (0, douCoh.end); 

douCoh << '}'; 
21

Si può cercare il stringstream e tornare 1 carattere, utilizzando stringstream::seekp. Si noti che non rimuove l'ultimo carattere, ma sposta solo la testina di scrittura. Questo è sufficiente in questo caso, poiché sovrascriviamo l'ultimo carattere con uno }.

douCoh << '{'; 
for(unsigned int i=0;i<dataSize;i++) 
    if(v[i].test) douCoh << i+1 << ','; 
douCoh.seekp(-1,douCoh.cur); douCoh << '}'; 
8

Ho avuto questo problema molto e ho scoperto che si può semplicemente fare:

douCoh.seekp(-1, std::ios_base::end); 

e il cassero l'inserimento dei dati. Come altri hanno affermato, evitare di inserire i dati errati in primo luogo è probabilmente la soluzione ideale, ma nel mio caso era il risultato di una funzione di libreria di terze parti, e volevo anche evitare di copiare i dati in stringhe.