Problema con la lectura de este archivo Binario

Iniciado por ProgramadorAnonimo, 27 Septiembre 2021, 20:36 PM

0 Miembros y 1 Visitante están viendo este tema.

ProgramadorAnonimo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct ARTI {
    short int ART;
    char COD[50];
    char DESC[100];
    char FAB[50];
    short int STOCK;
    int POS;
}    ;


int main()
{
    FILE * FP;
    struct ARTI X;


    if((FP = fopen("BDARTICULOSindexado","rb")) == NULL)
    {
        printf("\n\n\t ERROR EN LA APERTURA DEL ARCHIVO\n\n");
        exit(1);
    }

    fread(&X,sizeof(X),1,FP);
    printf("\n\n %5s %10s %30s %27s %8s %15s","ARTICULO","CODIGO","DESCRIPCION","FABRICANTE","STOCK","POSICION");

    while(!feof(FP))
    {
        printf("\n\n %5d %15s %35s %20s %8d %10d ",X.ART , X.COD , X.DESC , X.FAB , X.STOCK , X.POS);
        fread(&X,sizeof(X),1,FP);
    }


    fclose(FP);

    printf("\n\n\n\n");
}


El problema acá es que a la hora de ver en pantalla el printf con los datos muestra algunas cosas que están en la base de datos y otra parece basura del sistema; la base de datos es correcta porque ya la utilicé en otros programas. No se que hacer realmente, si me pudieran ayudar se los agradecería.

MOD: Etiqueta GeSHi

Locura_23

#1
Suele ser mejor utilizar el retorno de la función fread() para leer hasta el fin del archivo...
Prueba con esto


while(  fread(&X,sizeof(X),1,FP) > 0 )
{

   printf("\n\n %5d %15s %35s %20s %8d %10d ",X.ART , X.COD , X.DESC , X.FAB , X.STOCK , X.POS);
   
}


pregunta, en el nombre del archivo no deberías colocar la extensión ? ya sea .bin,  .dat

ProgramadorAnonimo

Mira, recién probé con el retorno de fread y sigue pasando lo mismo; y las extensiones la verdad las estábamos usando solo para los archivos de texto, en ningún momento me dijeron que utilizara una extensión para un archivo binario. No creo que la solución sea la extensión...

MAFUS

Te encontraste con un problema se serialización, o cómo se guardan internamente los datos y cómo se deben guardar cuando salen fuera.

La cosa es que por motivos de eficiencia un ordenador decide de qué forma guarda los datos de una estructura, que puede ser diferente a cómo se creó en código. Cuando le das a guardar esa estructura en un archivo directamente, lo que hace es copiar esa representación interna. Así que cuando lo vas a leer tiempo después o en otro ordenador la estructura interna de al estructura puede cambiar y el ordenador tratará de leerla como tiene en su modelo interno. Obviamente los datos no van a coincidir.

¿Qué debes hacer? Se debe guardar uno a uno los campos de la estructura y si uno de esos campos también es una estructura se tiene que desgranar igual. Para recuperar los campos se deben leer uno a uno en el mismo orden en que fueron grabado y colocados en la estructura; no leer la estructura directamente del archivo.

Locura_23

Tal vez puedes manejarte con los bytes del archivo ? pararte al principio del archivo con rewind() o fseek() y luego moverte tantos bytes (bytes de la estructura) hacia abajo, leer. Y así.

MAFUS

Aún así. No sabes cómo guardó el ordenador la estructura. Es un archivo binario así que no sabes dónde empiezan y terminan los campos. La solución es grabarlos uno mismo en el orden y leerlos el en mismo orden.

Serapis

Como te han dicho, la lectura de un fichero está ligado a la escritura del mismo.

Por ejemplo si para hacer la escritura, se escribió algún separador entre campos, o entre indices de la estructura, o incluso si para algún campo se usó un padding... La estructura indica sobre todo como se dispone en memoria, pero no necesariamente se guarda así en fichero. Incluso al guardarlo a fichero una función podría cambiar el orden de algún campo al escribirlo...
....esas mismas consideraciones deben usarse para la lectura, por ello es imprescindible tener la función de escritura a mano (donde puedas verla), para asegurarte que el formato de lectura coincide con el de escritura. Por supuesto considera que si sobrepasas el final de fichero, en efecto es normal obtener un urli-burli de datos.

Así tu primera preocupación tras abrir el fichero es comprobar si el número de registros guardado y dado el tamaño de cada registro (+ lo que ocupare una posible cabecera), coincide con el tamaño del fichero.
...y lo siguiente es alinear el puntero de lectura con la posición del primer registro (esto es,  saltando la cabecera que pudiera tener). Es habitual si hay cabeceras cuyo tamaño es variable, mantener en dicha cabecera, el puntero absoluto de comienzo del primer registro dentro del fichero.

En resumen cíñete al formato con que fue escrito, para lo que necesitas o bien tener el código fuente de la función que se escribió el fichero o bien una descripción en prosa con tales detalles.