C++ ficheros binarios y templates

22/05/2004 - 00:31 por opotonil | Informe spam
Hola.

Estaba intentando hacer una funcion en C++ que escribiera
en un fichero binario cualquier tipo de dato mediante
templates, pero no hay manera.

El codigo es el siguiente:

template <class T> void Fichero::f_escribir(string
nombre, T dato){
fichero.open(nombre.c_str(), ios::out |
ios::binary);
fichero.write(reinterpret_cast<const char*>
(&dato), sizeof(T));
fichero.close();
}

y el tipo de dato que le estoy pasando ahora mismo es:

struct grupos{
string nombre;
string comandos;
};

El fichero me lo crea pero vacio de 0 bytes.

ya de paso otra pregunta: la estructura puede estar
compuesta por datos de tipo string o no (ya que en el
string lo que imagino que haga sera crear un char
dinamico del tamaño necesario para alojar los datos de
manera que al leer del fichero con sizeof la estructura
cada vez tendra un tamaño).

Muchas gracias y salu2.
 

Leer las respuestas

#1 Isidro Muñoz
22/05/2004 - 23:15 | Informe spam
Hola,

Pongamos algunas ideas en orden.

Por ejemplo;

struct prueba
{
char nombre[50];
char direccion[200];
char telefono[10];
int estado;
} aux;

si hacemos fwrite(&aux,sizeof(aux)) // la sintaxis no es así pero es
irrelevante.

Funciona perfectamente porque le estamos diciendo que escriba el tamaño que
ocupa la estructura que en nuestro caso es 50+200+10+4
del puntero de memoria &aux, que es donde se empieza a almacenar la
estructura en memoria. Si luego leemos este dato y hacemos
fread(&aux,sizeof(aux), se quedaría igual que estaba anteriormente.

Ahora bien, si tenemos en la estructura puntero a otros datos ocurre lo
siguietne:

struct prueba
{
char *nombre;
char *direccion;
char *telefono;
int estado;
}

Si creamos una estructura

struct prueba aux;

aux.nombre=new char[50];
aux.direccion=new char[200];
aux.telefono=new.char[50];

El tamaño de esta estructura es 4 + 4 + 4 + 4 = 16, si almacenamos estos
datos luego al recuperarlos lo que recuperamos será el valor a donde apunta
nombre, direccion, telefono, que evidentemente no tienen nada que ver conlos
grabados.

Y si decimos por ejemplo printf("nombre %s",aux.nombre); evidentemente
aux.nombre apunta al valor original cuando se grabo o sea el new original, y
ahora tendriamos que hacer nuestra propia reserva, pero que
reservariamos si en el fihero lo que hemos almacenado son 4 bytes que es
el puntero que a apunta a la cadena nombre, luego no sabemos que podemos
recuperar.

Vamos a complicarlo mas, si hacemos

struct prueba
{
string nombre;
string direccion;
string telefono;
int telefono;
}

string es una clase, esa clase tendra unos miembros a efectos de datos se
almacena igual que una struct, lo que ocurre es que esa clase para almacenar
el buffer de cadena normalmente es dinámico con lo que usa un buffer que va
cambiando, entonces no te va a servir de nada porque te va ocurrir lo que
antes he expuesto, usa un puntero internalmente.

A parte de eso si usas clases, si esas clases tienen métodos virtual además
añade 4 bytes por cada método virtual que tenga, y si ya ademas usa
herencia, entonces seguramente ( no lo recuerdo bien) te generá 4 bytes
tambien por los métodos virtuales de los padre.

Si luego lees esos datos los punteros de los métodos virtuales seran
sustituidos por los antiguos, y a lo mejor no ocurre nada porque el
ejecutable se carga en las mismas posiciones de memoria, pero está claro que
por los buffer que usa de datos no te sirve este tema.

Saludos.
Isidro.

Preguntas similares