elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Archivo binario, al leerlo me muestra 2 veces el ultimo registro
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Archivo binario, al leerlo me muestra 2 veces el ultimo registro  (Leído 8,173 veces)
.:BlackCoder:.


Desconectado Desconectado

Mensajes: 388


Cada dia C++!!


Ver Perfil
Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« en: 4 Marzo 2011, 04:27 am »

Buenas, estaba retomando el tema de archivos pero me quede estancado  :xD

Código
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <fstream>
  4.  
  5. using namespace std;
  6.  
  7. class Personas{
  8.    private:
  9.        char Nombre[30];
  10.        int edad;
  11.    public:
  12.        Personas(char *x="",int e=0){
  13.            strcpy(Nombre,x);
  14.            edad=e;
  15.        }
  16.        const char* getNombre() const{
  17.            return Nombre;
  18.        }
  19.        int getEdad() const{
  20.            return edad;
  21.        }
  22.        void setNombre(const char cad[]){
  23.            strcpy(Nombre,cad);
  24.        }
  25.        void setEdad(const int e){
  26.            edad=e;
  27.        }
  28. };
  29.  
  30. void mostrar(){
  31.    ifstream ent("PRUEBA.dat",ios::in | ios::binary);
  32.    Personas aux;
  33.  
  34.    while(!ent.eof()){
  35.        ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas));
  36.        cout<<aux.getNombre()<<endl<<aux.getEdad()<<endl;
  37.    }
  38.    ent.close();
  39. }
  40.  
  41. int main(int argc, char *argv[])
  42. {
  43.    Personas persona("ALGUIEN",50);
  44.    Personas persona2("Otro",20);
  45.  
  46.    ofstream sal("PRUEBA.dat", ios::out | ios::binary);
  47.  
  48.    sal.write(reinterpret_cast<char *>( &persona ), sizeof(Personas));
  49.    sal.write(reinterpret_cast<char *>( &persona2 ), sizeof(Personas));
  50.    sal.close();
  51.  
  52.    mostrar();
  53.  
  54.    system("PAUSE");
  55.    return EXIT_SUCCESS;
  56. }

El programa muestra 2 veces el ultimo registro es decir, muestra:

ALGUIEN
50
Otro
20
Otro
20


Por que?


« Última modificación: 12 Marzo 2011, 05:57 am por .:BlackCoder:. » En línea

"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja



Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« Respuesta #1 en: 12 Marzo 2011, 18:33 pm »

Porque EOF devuelve true cuando ya pasaste por el final del archivo y no cuando estas a punto de pasarlo, por ende imprimes el contenido por duplicado.
Sigue paso por paso la ejecución del bucle en una hoja y chequea siempre cuales son los contenidos a imprimir, y quedara mas claro.

Por lo pronto puedes solucionarlo así:

Código
  1. while(!ent.eof() && ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas)))
  2. cout<<aux.getNombre()<<endl<<aux.getEdad()<<endl;
  3.  

Saludos


En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
.:BlackCoder:.


Desconectado Desconectado

Mensajes: 388


Cada dia C++!!


Ver Perfil
Re: Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« Respuesta #2 en: 12 Marzo 2011, 21:04 pm »

Probe y si funciona pero no comprendo bien que sucede... read() devuelve un flujo, cierto? Cuando haces:
Código
  1. while(!ent.eof() && ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas)))

aca la segunda condicion se cumple siempre y cuando no "lea" el eof...?

Crei que era lo mismo que:

Código
  1. while(ent.good())

Pero nop... Es que acaso el flujo "ent" no se coloca en mal estado cuando lee el EOF?...
En línea

"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja



Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« Respuesta #3 en: 12 Marzo 2011, 21:55 pm »

Claro, por eso dije "por lo pronto"; para que puedas ver la lógica del error.
En la ultima lectura se establece failbit y ent.read devuelve NULL en lugar de *this, ergo la condición ya no se cumple y por eso los datos no se repiten.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
.:BlackCoder:.


Desconectado Desconectado

Mensajes: 388


Cada dia C++!!


Ver Perfil
Re: Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« Respuesta #4 en: 12 Marzo 2011, 22:43 pm »

ent.read devuelve NULL en lugar de *this

Gracias  :D, no sabia esa parte, crei que devolvia *this, y si ponia el failbit en mal estado...

En la ultima lectura se establece failbit

Pero si en la ultima se establece failbit porque esto no funciona?

Código
  1. while(!ent.fail()){
  2.        ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas));
  3.        cout<<aux.getNombre()<<endl<<aux.getEdad()<<endl;
  4.    }

Yo creo que ciertamente devuelve null en vez de *this por el error... pero no establece por si sola el failbit en mal estado...

Hice esto para usar la condicion con good(), no muestre el de nuevo el ultimo registro... Y no poner la lectura en la condicion del while (se ve raro xD)
Código
  1.    while(ent.good()){
  2.        if (ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas)))
  3.            cout<<aux.getNombre()<<endl<<aux.getEdad()<<endl;
  4.        }


Saludos...
En línea

"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja



Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« Respuesta #5 en: 12 Marzo 2011, 23:25 pm »

Código
  1. while(!ent.fail()){
  2.        ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas));
  3.        cout<<aux.getNombre()<<endl<<aux.getEdad()<<endl;
  4.    }

Esto no funciona como esperas porque cometes el mismo error que en el código anterior. Cuando ent.read devuelve NULL y se establece failbit, vos todavía estas dentro del bloque de ejecución del ciclo, por lo tanto imprimís una vez mas el contenido que leíste en la pasada anterior.

En cuanto a lo de failbit, no lo he probado, pero estoy seguro, de hecho si así no fuese el código anterior seria un ciclo infinito. Prueba revisando los valores de retorno (para eso están ;D ) y quedara mas claro!

Código
  1. while(!ent.fail()){
  2.        cout<<"Read return value: "<<ent.read(reinterpret_cast<char *> (&aux),sizeof(Personas))<<endl;
  3.        cout<<aux.getNombre()<<endl<<aux.getEdad()<<endl;
  4.    }
  5.  

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
.:BlackCoder:.


Desconectado Desconectado

Mensajes: 388


Cada dia C++!!


Ver Perfil
Re: Archivo binario, al leerlo me muestra 2 veces el ultimo registro
« Respuesta #6 en: 13 Marzo 2011, 05:58 am »

Ah ya me puse a probar un poco de cosas y vi que el failbit se coloca en true es despues de leer el EOF mas no al momento de leerlo...

Gracias por la ayuda me habia quedado trancado con esa duda  :xD

Saludos...
En línea

"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines