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

José Luis Torre joseluistorrehernandez en gmail.com
Sab Jul 21 21:58:19 CEST 2012


Date cuenta que la stuct tficha la estás definiendo de diferente modo,
en un caso char telefono[10] y en el otro long telefono.




El día 21 de julio de 2012 12:43, Oscar <pelucheloko en hotmail.com> escribió:
> Hola Steven.
>
> He dejado el archivo que escribe el binario así:
>
>
> #include <fstream>
> #include <iostream>
> using namespace std;
>
> struct tficha {
>    char nombre[256];
>    char telefono[10];
>
>    };
>
> int main()
> {
>    tficha ficha;
>    int n;
>
>    ofstream vfile;
>    vfile.open("pruebas.dat", ios::out | ios::binary);
>
>
>    for(n=0; n<=3; n++)
>    {
>        cout << "escriba su nombre: ";
>        cin >> ficha.nombre;
>        cout << "escriba un telefono: ";
>        cin >> ficha.telefono;
>        vfile.write(reinterpret_cast<const char *>(&ficha), sizeof(ficha));
>    }
>    return 0;
> }
>
> Y el de lectura así:
>
>
> #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));
>    };
>    return 0;
> }
>
> Pero sigue dándome resultados extraños en la lectura de los valores, solo
> sale bien el nombre primero que escribo, pero el resto de caracteres leídos
> me salen caracteres extraños y sin sentido, no se que puede estar fallando,
> parece como que está leyendo otra cosa.
>
> Un saludo.
>
>
> -----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
>
> _______________________________________________
> 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



-- 
José Luis Torre
ww.ehu.es




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