[C con Clase] Duda y errores con manejo de ficheros
Oscar
pelucheloko en hotmail.com
Sab Jul 21 12:43:40 CEST 2012
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
Más información sobre la lista de distribución Cconclase