Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Archivos binarios indexados

Estas en el tema de Archivos binarios indexados en el foro de C/C++ en Foros del Web. Buenas, estoy leyendo el libro "Programacion avanzada UNIX", y cada X paginas salen unos ejercicios, pero me tope con uno que no lo entiendo. -Se ...
  #1 (permalink)  
Antiguo 15/09/2008, 01:44
 
Fecha de Ingreso: marzo-2008
Mensajes: 37
Antigüedad: 16 años, 1 mes
Puntos: 0
Archivos binarios indexados

Buenas, estoy leyendo el libro "Programacion avanzada UNIX", y cada X paginas salen unos ejercicios, pero me tope con uno que no lo entiendo.

-Se trata de escribir en un fichero X registros(los que queramos) y escribir un programa que lo ordene, pero no reescribiendo los registros en el fichero, sino por unos punteros de indices. Uhm, mejor pongo la explicacion del libro:

3.5 Queremos escribir un programa para ordenar ficheros binarios indexados que contienen informacion sobre los empleados. La estructura de estos ficheros es la siguiente:

Código:
Código:
#if !defined(_EMPLEADOS_H_)
#define _EMPLEADOS_H_

#define MAX 20

typedef struct
{
        char nombre[MAX];
        char sueldo[15];
}EMPLEADO;

typedef struct
{
        long nro_indices;  //total registros tipo EMPLEADO
        long *indices; //puntero a los indices que indican el orden en que deben
                               //leerse los registros del fichero. En el pie del fichero habran
                              //tantos indices como registros tenga el fichero
}PIE;

typedef struct
{
        int descriptor;  //puntero a la estructura de control
        PIE pie;  //Pie del fichero. Se debe leer del fichero referenciado por el campo
                      //descriptor.
}FICHERO;

#endif

Observese como al recorrer los indices del pie del fichero antes de ser ordenado, la secuencia que se obtiene es:

Tirante el blanco, 23.000 reales
Palmerin, 19.000 reales
Olivante, 35.000 reales

Sin embargo, al recorrer los indices del fichero ordenado la secuencia queda:

Olivante, 35.000 reales
Palmerim, 19.000 rales
Tirante el blanco, 23.000 reales

Por lo tanto el proceso de ordenacion consiste en cambiar los indices que figuran en el pie del fichero, los registros de datos no subren ninguna alteracion.


FICHERO *abrir_fichero(char *nombre);

La funcion abrir fichero debe abrir un fichero con la estructura descrita y cuyo nombre recibe a traves de la cadena de nombre, una vez abierto se debe crear en memoria una estructura con el formato FICHERO que contenga:

i. Un puntero a la estructura de control del fichero.
ii. Una copia en memoria del pie del fichero, es decir, el total de registros del fichero y la sequencia de indices

-Entonces, se hacen 3 programas, uno para crear el fichero y los registros y escribirlos en el fichero, que es este:

Código:

Código:
#include "empleados.h"
#include "error.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#define FF(str) str[strlen(str)-1]=0
#define modo (O_WRONLY | O_CREAT)

FICHERO *abrir_fichero(char *nom_fichero)
{
        FICHERO *f;

        if((f=(FICHERO *)malloc(sizeof(FICHERO)))==NULL)
                   error(errno,"allocate memory for struct failed");

        if((f->descriptor=open(nom_fichero,modo,0600))==-1)
          {
                free(f);
                error(errno,"open file fail");
          }

        f->pie.nro_indices=0;
        f->pie.indices=NULL;

        return(f);
}

void cerrar_fichero(FICHERO *f)
{

         long i;

         f->pie.indices=(long *)malloc(f->pie.nro_indices*sizeof(long));

         printf("%d \n",f->pie.nro_indices);


         if(f->pie.indices==NULL)
                 error(errno,"long malloc");

         for(i=0 ; i < f->pie.nro_indices ; i++)
                   f->pie.indices[i]=i;
                   
            
         write(f->descriptor, f->pie.indices,sizeof(long)*f->pie.nro_indices);
         write(f->descriptor, &f->pie.nro_indices, sizeof(long));



         close(f->descriptor);
}

EMPLEADO *leer_registro(void)
{
        static EMPLEADO e;

        printf("Nombre: ");

        if((strlen(fgets(e.nombre,14,stdin))) < 2)
                          return NULL;
          
        FF(e.nombre);


        printf("Sueldo: ");

       scanf("%f",&e.sueldo);

        getchar();

        return(&e);

}

escribir_registro(FICHERO *f, EMPLEADO e)
{      
        write(f->descriptor,&e,sizeof(e));
        ++f->pie.nro_indices;
        
}

int
main(int argc, char **argv)
{
        EMPLEADO *e;
        FICHERO *f;

        argc != 2 ? exit(-1) : NULL;

        f=abrir_fichero(argv[1]);



        while((e=leer_registro())!=NULL)
                escribir_registro(f,*e);
        cerrar_fichero(f);

return 0;
}

Esto lo entiendo, menos estas dos lineas:

Código:
Código:
write(f->descriptor, f->pie.indices,sizeof(long)*f->pie.nro_indices);
         write(f->descriptor, &f->pie.nro_indices, sizeof(long));


(c) Escribir una funcion con la declaracion siguiente:
Código:
char *leer_nombre(FICHERO *f, long n);
Esta funcion devolvera el nombre del empleado que ocupa la posicion referenciada por el indice numero n del fichero controlado por f.

Tengase en cuenta que n no es el numero de registro, sino el numero del indice que contiene el numero de registro

Esto tambien me tiene confuso, no se como obtenerlo a partir de cuando abro el fichero, se supone que deberia de leerlo del fichero.


Ahora el quit viene en lo siguiente, estoy haciendo el programa leer, que se encarga de leer la estructura de datos del fichero y presentarla por pantalla.


Código:

Código:
void *leer_fichero(FICHERO *f)
{

        EMPLEADO e;
        int nbytes;

        while((nbytes=read(f->descriptor,&e,sizeof(e))) > 0)
              printf("Nombre: %s\tSueldo: %f\n",e.nombre,e.sueldo);




        close(f->descriptor);
        free(f);
}
Me sale esto:

Nombre: Osca Sueldo: 1
Nombre: Pepe Sueldo: 3
Nombre: Sueldo: 3

Y yo solo he añadido 2 registros, tampoco se como obtener el total de indices del pie del fichero como indica el ejercicio, a partir del descriptor. A ver si alguien me puede echar un cable, este ejercicio me tiene bastante confuso

Gracias de antemano y siento el toston
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:45.