recorrer archivo binario

Iniciado por m@o_614, 18 Octubre 2013, 23:22 PM

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

m@o_614

Saludos

Si tengo un arreglo de estructuras(o de registros), los cuales guardo en un archivo binario, para yo poder recorrer registro por registro(tomando en cuenta que tienen diferente longitud) en un archivo binario tengo que hacerlo secuencialmente o sea caracter por caracter, o puedo ir saltando de registro en registro hasta encontrar el que busco?? tengo que poner delimitadores entre cada registro para saber donde empieza uno y donde termina otro??

gracias

eferion

Tienes varias opciones:

* Crea un segundo archivo que contenga un índice. Este índice te debería indicar la posición en la que comienza cada registro y, adicionalmente, puede contener algún otro valor del registro que te permita acelerar las búsquedas ( por ejemplo el nombre si los registros almacenan datos de tus contactos. Esto te permite buscar en el índice por los nombres y localizar rápidamente la posición del registro que estás buscando ).

* Puedes poner antes de cada registro un campo que indique la longitud total de dicho registro... así si lo quieres saltar basta con que incrementes el puntero de lectura en X para acceder al siguiente campo de longitud.

* Puedes integrar el archivo del índice que te he comentado antes al final ( o al principio ) del archivo... entonces para hacer búsquedas puedes ir rápidamente a dicho índice para hacer la búsqueda.

* Puedes plantearte añadir un "padding" a cada registro para que todos acaben ocupando lo mismo... de esta forma los saltos serán siempre iguales.

Y seguro que a alguno más se le ocurren ideas nuevas.

m@o_614

#2
muchas gracias eferion por tu respuesta, el programa lo que hace es que me pide que le ingrese 10 registros que contengan(nombre,edad y ciudad residencia) y despues me pide un numero del 1 al 10 y me tiene que imprimir ese registro, el problema es que si le pido por ejemplo el registro numero 2 y este registro es:

marco22guadalajara, (nombre,edad, ciudad) el programa me imprime marco22guadalajar, o sea que se come la ultima letra y ya lo revise pero no entiendo por que hace esto

El programa basicamente me hace un arreglo del tamanio de cada registro para ver donde esta cada uno
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 35
#define TAM 10
/*
  Ampliar el programa anterior para que use un "array de structs", de forma que se puedan tener datos de 10 personas.
  Se deberán pedir  los datos de las 10 personas y guardarlos en el fichero, Después se pedirá un número del 1 al 10
  y se mostrarán los datos de la persona indicada por ese número,que se deberán leer de fichero
  (1 será la primera ficha, y 10 será la última). Por ejemplo,
  si el usuario indica que quiere ver los datos de la persona 3 (tercera), se deberá leer las dos primeras,
  ignorando su contenido, y después leer la tercera, que sí se deberá mostrar.
*/
typedef struct datos
{
   char nombre[MAX];
   int edad;
   int tamanio;
   char ciudad_residencia[MAX];
}Persona;

void agregarRegistro(Persona p[],int i);
void buscarRegistro(FILE *ap,int numeroRegistro,int arregloTam[]);

int main()
{
   Persona p[TAM];
   int i,numeroRegistro,tamanioRegistro,suma = 0,arregloTam[TAM];
   FILE *fd,*ap;
   if((fd = fopen("F:\\gente.txt","w+"))!= NULL)
   {
       for(i = 0;i < TAM;i++)
       {
           agregarRegistro(p,i);
           fprintf(fd,"%s%d%s",p[i].nombre,p[i].edad,p[i].ciudad_residencia);
           fseek(fd,0,SEEK_END);
           tamanioRegistro = (ftell(fd) - suma);
           arregloTam[i] = tamanioRegistro;
           suma+=tamanioRegistro;
           system("cls");
       }
       fclose(fd);
       if((ap = fopen("F:\\gente.txt","r"))!= NULL)
       {
           printf("Dame un numero(del 1 al 10): ");
           scanf("%d",&numeroRegistro);
           buscarRegistro(ap,numeroRegistro,arregloTam);
       }
       else
          printf("No se pudo abrir archivo");
   }
   else
      printf("No se pudo crear archivo");
   return 0;
}

void agregarRegistro(Persona p[],int i)
{
   char cad[10],*ptr;
   printf("Dame nombre:\n");
   fgets(p[i].nombre,MAX,stdin);
   if((ptr = strchr(p[i].nombre,'\n'))!= NULL)
      *ptr = '\0';
   printf("Dame edad:\n");
   fgets(cad,sizeof(cad),stdin);
   sscanf(cad,"%d",&p[i].edad);
   printf("Dame ciudad de residencia:\n");
   fgets(p[i].ciudad_residencia,MAX,stdin);
   if((ptr = strchr(p[i].ciudad_residencia,'\n'))!= NULL)
      *ptr = '\0';
}

void buscarRegistro(FILE *ap,int numeroRegistro,int arregloTam[])
{
   int i = 0,posicion,tam;
   char Registro[100];
   fseek(ap,0,SEEK_SET);
   while(i < numeroRegistro-1)
   {
       posicion = arregloTam[i];
       fseek(ap,posicion,SEEK_CUR);
       i++;
   }
   tam = arregloTam[i];
   fgets(Registro,tam,ap);
   printf("%s",Registro);
}


rir3760

El problema se encuentra en la funcion "buscarRegistro", en la linea:
fgets(Registro, tam, ap);
Y se debe a que le estas indicando el numero exacto de caracteres del registro pero la función utilizara el ultimo para almacenar el '\0'.

Para solucionarlo basta con tener eso en cuenta cambiando la llamada a fgets a:
fgets(Registro, tam + 1, ap);

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language