2010-12-28 10 views
12

En mi código hay un bucle que agrega algo así como ese "número" a stringstream. Cuando termine, necesito extraer ',' agregar '}' y agregar '{' si el ciclo se repite.eliminar char de stringstream y anexar algunos datos

Pensé que podía usar ignore() para eliminar ',' pero no funcionó. ¿Sabes cómo puedo hacer lo que describo?

ejemplo:

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

Por favor, agregue algunos ejemplos para ilustrar su punto. –

Respuesta

22

Puede extraer la cadena (con el miembro str()), eliminar el último carácter con std::string::erase y luego restablecer la nueva cadena como búfer al std::ostringstream.

Sin embargo, una mejor solución sería la de no insertar la superflua ',', en primer lugar, por hacer algo así:

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

Maldita sea, fuiste más rápido unos segundos ... – RedX

+0

nice; tómalo :) –

0

Usted podría utilizar std::string::erase para eliminar el último carácter directamente de la cadena subyacente.

+1

¿Cómo puedo obtener la cadena subyacente? str() devuelve una copia de cadena no una referencia, ¿no? –

+0

Sí, obtienes una copia de los contenidos usando str(). – RedX

+1

Hay otra modificación de la función 'std :: ostringstream :: str' que permite cambiar el búfer. Sin embargo, esta solución cuesta dos copias del contenido del búfer, que puede ser costoso. –

0

Por qué no sólo comprobar el contador? Y no inserte el ''

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

Creo que no es posible verificar el contador ya que puede haber algunos objetos que no pasan la prueba. Se requiere otro contador (que puede ser un bool), o se puede usar mi truco para cambiar la variable separadora. –

+0

Es imposible predecir el valor de v [j] .test para j> i antes de la coditional. –

0

Diviértete con std :: copia, iteradores y rasgos. Debe asumir que sus datos son iterables de forma inversa (final - 1) o que su resultado puede rebobinarse. Elijo que era más fácil de rebobinar.

#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

O bien, debe escribir el ciclo completo en lugar de confiar en std :: copy. –

+0

Creo que quería evitar escribir toneladas de código ... –

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

¡Bienvenido a StackOverflow! Sería útil si explicaras tu código para aquellos que no lo entienden. – ajacian81

+0

+1. Este es mi favorito personal. – refi64

0

que he encontrado de esta manera, utilizando el método de cadena pop_back() ya que C++ 11. Probablemente no tan bueno como los más inteligentes anteriores, pero útil en casos mucho más complicados y/o para personas perezosas.

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

Usted puede buscar la stringstream y volver 1 carácter, utilizando stringstream::seekp. Tenga en cuenta que no elimina el último carácter, sino que solo mueve el encabezado de escritura. Esto es suficiente en este caso, ya que sobrescribimos el último carácter con un }.

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

he tenido este mismo problema y descubrí que sólo tiene que hacer:

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

Y el torreón inserción de datos. Como dijeron otros, evitar la inserción de datos erróneos en primer lugar es probablemente la solución ideal, pero en mi caso fue el resultado de una función de biblioteca de terceros, y también quería evitar copiar los datos en cadenas.