[C con Clase] Duda y errores con manejo de ficheros

Oscar pelucheloko en hotmail.com
Sab Jul 21 12:45:10 CEST 2012


No perdón ya está (olvidé modificar el valor de long telefono a char 
telefono[10] en el archivo que lee los datos).

¡¡¡¡Gracias!!!!!

-----Mensaje original----- 
From: Steven Davidson
Sent: Saturday, July 21, 2012 2:52 AM
To: Lista de correo sobre C y C++
Subject: Re: [C con Clase] Duda y errores con manejo de ficheros

Hola Óscar,

On 7/20/2012 8:24 PM, Oscar wrote:
> Hola que tal.
> He hecho dos programillas, uno para escribir en un archivo binario
> los datos de una estructura, datos de variables miembro (no se si se

Sí; o simplemente, "datos miembro".

> diría así), luego posteriormente los quiero recuperar en otro código,
> pero no soy capaz, no alcanzo a ver lo que hago mal.
> Primero os pego el código del programa que crea el binario donde van
> los datos:

Veamos el código fuente.

> #include <fstream>
> #include <iostream>
> using namespace std;
> struct tficha {
>      char nombre[256];
>      long telefono;

En general, no es recomendado representar un teléfono como un número, ya
que su formato implica caracteres: paréntesis, guiones, e incluso
letras. Sugiero usar una cadena de caracteres.

> };
> int main()
> {
>      tficha ficha;
>      int n;
>      ofstream vfile;
> vfile.open("pruebas.dat", ios::binary);

Se te ha olvidado indicar 'ios::out'. Esto es,

vfile.open( "pruebas.dat", ios::out | ios::binary );

>      for(n=0; n<=3; n++)
> {
>          cout << "escriba su nombre: ";
>          cin >> ficha.nombre;
>          vfile << ficha.nombre;
>          cout << "escriba un telefono: ";
>          cin >> ficha.telefono;
>          vfile << ficha.telefono;
>          vfile.write((char *) &ficha, sizeof(ficha));

Estás haciendo tres escrituras, cuando en realidad sólo necesitas hacer
una - la última. Las dos escrituras anteriores son con formato, mientras
que lo que quieres es que sean sin formato.

Recuerda que 'ficha.nombre' puede contener cualquier cantidad de
caracteres y desde luego no va a ser 256 caracteres, ya que el carácter
nulo se ignora para esta interpretación.

El otro problema es con:

vfile << ficha.telefono;

ya que el operador << interpretará el valor en 'ficha.telefono' y
escribirá una cadena de caracteres que representa tal valor.

Los operadores sobrecargados << y >> son de entrada y salida con
formato. Como te interesa escribir en binario para que los datos en
memoria se guarden exactamente en un fichero, no puedes usar estos
formatos ni conversiones a caracteres.

Sólo tienes que hacer esto:

vfile.write( reinterpret_cast< const char * >( &ficha ), sizeof ficha );

Esto te escribe los bytes en 'ficha'; sin formatos ni conversiones, y
además rápidamente.

> }
> vfile.close();

Esto no es necesario. Pero lo que sí es necesario es:

return 0;

> }
> Luego aquí va el código del programa que debería leer esos datos:
> #include <fstream>
> #include <iostream>
> using namespace std;
> struct tficha {
>      char nombre[256];
>      long telefono;
> };
> int main()
> {
>      tficha ficha;
>      int n;
>      ifstream vfile;
> vfile.open("pruebas.dat", ios::in | ios::binary);
> vfile.read((char *) &ficha, sizeof(ficha));
>      while (!vfile.eof())
> {
>          cout << "nombre: " << ficha.nombre << endl;
>          cout << "telefono: " << ficha.telefono << endl;
>          vfile.read((char *) &ficha, sizeof(ficha));
> };
> vfile.close();

Nuevamente, no es necesario ser explícito con el cierre del fichero,
pero sí necesitas retornar un entero en 'main()'.

> }


Espero que haya aclarado el asunto.

Steven



_______________________________________________
Lista de correo Cconclase Cconclase en listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ 





Más información sobre la lista de distribución Cconclase