[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