Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: m@o_614 en 18 Octubre 2013, 23:22 pm



Título: recorrer archivo binario
Publicado por: m@o_614 en 18 Octubre 2013, 23:22 pm
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


Título: Re: recorrer archivo binario
Publicado por: eferion en 19 Octubre 2013, 19:40 pm
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.


Título: Re: recorrer archivo binario
Publicado por: m@o_614 en 21 Octubre 2013, 21:39 pm
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
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define MAX 35
  5. #define TAM 10
  6. /*
  7.    Ampliar el programa anterior para que use un “array de structs”, de forma que se puedan tener datos de 10 personas.
  8.    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
  9.    y se mostrarán los datos de la persona indicada por ese número,que se deberán leer de fichero
  10.    (1 será la primera ficha, y 10 será la última). Por ejemplo,
  11.    si el usuario indica que quiere ver los datos de la persona 3 (tercera), se deberá leer las dos primeras,
  12.    ignorando su contenido, y después leer la tercera, que sí se deberá mostrar.
  13. */
  14. typedef struct datos
  15. {
  16.    char nombre[MAX];
  17.    int edad;
  18.    int tamanio;
  19.    char ciudad_residencia[MAX];
  20. }Persona;
  21.  
  22. void agregarRegistro(Persona p[],int i);
  23. void buscarRegistro(FILE *ap,int numeroRegistro,int arregloTam[]);
  24.  
  25. int main()
  26. {
  27.    Persona p[TAM];
  28.    int i,numeroRegistro,tamanioRegistro,suma = 0,arregloTam[TAM];
  29.    FILE *fd,*ap;
  30.    if((fd = fopen("F:\\gente.txt","w+"))!= NULL)
  31.    {
  32.        for(i = 0;i < TAM;i++)
  33.        {
  34.            agregarRegistro(p,i);
  35.            fprintf(fd,"%s%d%s",p[i].nombre,p[i].edad,p[i].ciudad_residencia);
  36.            fseek(fd,0,SEEK_END);
  37.            tamanioRegistro = (ftell(fd) - suma);
  38.            arregloTam[i] = tamanioRegistro;
  39.            suma+=tamanioRegistro;
  40.            system("cls");
  41.        }
  42.        fclose(fd);
  43.        if((ap = fopen("F:\\gente.txt","r"))!= NULL)
  44.        {
  45.            printf("Dame un numero(del 1 al 10): ");
  46.            scanf("%d",&numeroRegistro);
  47.            buscarRegistro(ap,numeroRegistro,arregloTam);
  48.        }
  49.        else
  50.           printf("No se pudo abrir archivo");
  51.    }
  52.    else
  53.       printf("No se pudo crear archivo");
  54.    return 0;
  55. }
  56.  
  57. void agregarRegistro(Persona p[],int i)
  58. {
  59.    char cad[10],*ptr;
  60.    printf("Dame nombre:\n");
  61.    fgets(p[i].nombre,MAX,stdin);
  62.    if((ptr = strchr(p[i].nombre,'\n'))!= NULL)
  63.       *ptr = '\0';
  64.    printf("Dame edad:\n");
  65.    fgets(cad,sizeof(cad),stdin);
  66.    sscanf(cad,"%d",&p[i].edad);
  67.    printf("Dame ciudad de residencia:\n");
  68.    fgets(p[i].ciudad_residencia,MAX,stdin);
  69.    if((ptr = strchr(p[i].ciudad_residencia,'\n'))!= NULL)
  70.       *ptr = '\0';
  71. }
  72.  
  73. void buscarRegistro(FILE *ap,int numeroRegistro,int arregloTam[])
  74. {
  75.    int i = 0,posicion,tam;
  76.    char Registro[100];
  77.    fseek(ap,0,SEEK_SET);
  78.    while(i < numeroRegistro-1)
  79.    {
  80.        posicion = arregloTam[i];
  81.        fseek(ap,posicion,SEEK_CUR);
  82.        i++;
  83.    }
  84.    tam = arregloTam[i];
  85.    fgets(Registro,tam,ap);
  86.    printf("%s",Registro);
  87. }


Título: Re: recorrer archivo binario
Publicado por: rir3760 en 25 Octubre 2013, 17:59 pm
El problema se encuentra en la funcion "buscarRegistro", en la linea:
Código
  1. 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:
Código
  1. fgets(Registro, tam + 1, ap);

Un saludo