2011-02-01 15 views
11

Tengo un std::vector<int> y quiero serializarlo. Para este propósito que estoy tratando de utilizar un std::stringstreamCómo copio datos binarios a un stringstream

vector<int> v; 
v.resize(10); 
for (int i=0;i<10;i++) 
v[i]=i; 


stringstream ss (stringstream::in | stringstream::out |stringstream::binary); 

Sin embargo, cuando copio el vector al stringstream esta copia como personaje

ostream_iterator<int> it(ss); 
copy(v.begin(),v.end(),it); 

el valor que introduce para amortiguar (_Strbuf) es "123456789 "

I sucssesed escribir una solución de solución

for (int i=1;i<10;i++) 
    ss.write((char*)&p[i],sizeof(int)); 

quiero hacer algo como primera forma utilizando la función std como copiar

gracias Herzl

Respuesta

10

En realidad, esta es su solución, pero se puede utilizar con el algoritmo std :: copy().

template<class T> 
    struct serialize 
    { 
     serialize(const T & i_value) : value(i_value) {} 
     T value; 
    }; 

    template<class T> 
    ostream& operator <<(ostream &os, const serialize<T> & obj) 
    { 
     os.write((char*)&obj.value,sizeof(T)); 
     return os; 
    } 

Uso

ostream_iterator<serialize<int> > it(ss); 
copy(v.begin(),v.end(),it); 
+0

Me gusta este enfoque en general, pero a menudo es un error para dar salida a la memoria a ciegas Me gusta esto. Aún necesita escribir algo que pueda serializar correctamente cada tipo. –

+0

Totalmente de acuerdo. Nunca usaría ese código en producción. Preferiría el ciclo "para" arriba mencionado :-) – Stas

2

Sé que esto no es una respuesta a su problema, pero si usted no está limitado a la STL se podría tratar (boost serialization) o google protocol buffers

Boost incluso tiene construir-en el soporte para contenedores STL de-/serialización (http://www.boost.org/doc/libs/1_45_0/libs/serialization/doc/tutorial.html#stl)

+0

gracias omer pero necesito conectar a un hardware y como veo aumentar agregar algunos datos de control a los datos (tipo de clase) –

1

Para usar std :: copy con ostream :: write, necesitaría escribir su propio iterador de salida que sepa cómo correc Tly serializar el tipo. Dicho esto, no estoy seguro de lo que espera obtener de este enfoque, pero en ese here's a first pass para ver un ejemplo:

struct ostream_write_int 
    : std::iterator<std::output_iterator_tag, int, void, void, void> 
{ 
    std::ostream *s; 
    ostream_write_int(std::ostream &s) : s (&s) {} 

    ostream_write_int& operator++() { return *this; } 
    ostream_write_int& operator++(int) { return *this; } 
    ostream_write_int& operator*() { return *this; } 

    void operator=(int x) { 
    s->write(reinterpret_cast<char*>(&x), sizeof(x)); 
    } 
}; 

Esto podría ser templated sólo si usted difiere de la lógica de serialización a alguna otra función (como el los iteradores de flujo formateados lo hacen al operador < <).

1

como Fred, no veo el punto de esto, lo que está intentando hacer es efectiva:

ss.rdbuf()->sputn(reinterpret_cast<char*>(&v[0]), sizeof(int) * v.size()); 
+1

Esto no es muy legible. Nunca entendería ese código fácilmente. –

+0

@the_drow, "nunca" es mucho tiempo! ;), puede reemplazar '.rdbuf() -> sputn (' con '.write (' si lo desea, es lo mismo ... – Nim

+1

Esto es cierto para el caso de un vector, pero un iterador que escribe cada elemento (como en la mía o en las respuestas de Stas) se puede usar con cualquier iterador de entrada, como por ejemplo std :: list. –

Cuestiones relacionadas