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

Problema con busqueda en ficheros binarios en C

Estas en el tema de Problema con busqueda en ficheros binarios en C en el foro de C/C++ en Foros del Web. Hola buenas a todos estoy realizando un proyecto que gestiona el personal y las ventas de una empresa, y tengo un problema con la busqueda ...
  #1 (permalink)  
Antiguo 01/06/2007, 12:33
 
Fecha de Ingreso: junio-2007
Mensajes: 2
Antigüedad: 16 años, 11 meses
Puntos: 0
Pregunta Problema con busqueda en ficheros binarios en C

Hola buenas a todos estoy realizando un proyecto que gestiona el personal y las ventas de una empresa, y tengo un problema con la busqueda dentro de un fichero binario, os pongo la funcion en cuestion ya que el codigo entero es muy largo aunque si alguien lo pide lo posteare.

Tengo al personal en un fichero y las ventas en otro, la cuestion es que si borro un empleado debo borrar tambien todas las ventas que a realizado y no me funciona esa parte.

Si alguien me pudiera ayudar estaria muy agradecido


Estas son las estructuras, he intentado realiazar la tarea de borrar las ventas que ha realizado una persona, ambas coinciden por el campo NIF.
Para ello he recorido el fichero de ventas moviendo la posicion bloque a bloque con el tamaño de la estructura, comparando el NIF del la estructura ventas con NIF de la persona ha borrar. Y no me funciona.

Que esta mal en el codigo?
Código:
struct persona
{
    char nif[tam];
    char nombre[tam];
    char direccion[tam];
    char tf[tam];
    int puesto;
    float comision;
    int control_alta;
};
struct venta
{
    char nif[18];
    float cantidad;
    char fecha[10];
    int control_alta;
};
Código:
void bajaspersonal()
{
    FILE *canal;
    FILE *canal2;
    struct persona p;
    struct venta v;
    int num;

    while((canal=fopen("personal","r+b"))==NULL)
    {
        canal=fopen("personal","wb");
        fclose(canal);
    }
    while((canal2=fopen("ventas","r+b"))==NULL)
    {
        canal=fopen("ventas","wb");
        fclose(canal);
    }
    do
    {
        fflush(stdin);
        do
        {
            clrscr();
            gotoxy(21,7);
            printf("Introduce el numero de cliente:  ");
            scanf("%d",&num);
        }
        while(num<1||num>MAX);
        p.control_alta='0';
        fseek(canal,(num-1)*sizeof(struct persona),SEEK_SET);
        fread(&p,sizeof(struct persona),1,canal);
        if(p.control_alta!='1')
        {
            gotoxy(10,20);
            printf("Empleado no existente");
        }
        else
        {
            pantalla_datos();
            gotoxy(17,7);
            printf("%s",p.nif);
            gotoxy(17,9);
            printf("%s",p.nombre);
            gotoxy(17,11);
            printf("%s",p.direccion);
            gotoxy(17,13);
            printf("%s",p.tf);
            gotoxy(54,13);
            printf("%f",p.comision);
            gotoxy(25,18);
            printf("Puesto %s",puestos[p.puesto-1]);
            printf("\nSe borraran todas las ventas realizadas por este empleado");
            if(pregunte_s_n("\nConfirma la baja?(S/N):")=='S')
            {/*Borra las ventas y el empleado*/
                for(int i=0;i<=numven && !feof(canal2);i++) /* numven contiene el numero de ventas que se han realizado*/
                { //Mientras no llege al final del archivo y haya ventas
                    fseek(canal2,i*sizeof(struct venta),SEEK_SET);
                    fread(&v,sizeof(struct venta),1,canal2);
                    if(p.nif==v.nif)
                    {
                        v.control_alta='0'; // Borra la venta del empleado
                        fseek(canal2,(i-1)*sizeof(struct venta),SEEK_SET);
                        fwrite(&v,sizeof(struct venta),1,canal2);
                        numven-=num;
                    }
                }
                p.control_alta='0';//Borra el empleado
                fseek(canal,(num-1)*sizeof(struct persona),SEEK_SET);
                fwrite(&p,sizeof(struct persona),1,canal);
                numper=num-1;
            }
        }
    }
    while(pregunte_s_n("Mÿs bajas?(S/N):")=='S');
    menupersonal();
    fclose(canal);
    fclose(canal2);
}

Última edición por neyboll; 01/06/2007 a las 19:46
  #2 (permalink)  
Antiguo 01/06/2007, 15:05
 
Fecha de Ingreso: mayo-2006
Mensajes: 40
Antigüedad: 18 años
Puntos: 0
Re: Problema con busqueda en ficheros binarios en C

Hace mucho tiempo puse un ejemplo simple en este foro http://foros.solocodigo.com/index.ph...531&hl=archivo de cómo dar de alta, de baja y modificar registros en un archivo usando las funciones de la librería estandar de C stdio.
En el ejemplo realmente no doy de baja los registros, sino sólo les pongo una marca que me indican que ya no están disponibles. Me parece que haces lo mismo según pude ver en lo que pusiste, aunque no estoy seguro. ¿Es esto lo que estás haciendo en tu programa? ¿sólo los marcas para indicar que están borrados? ¿cuál es el problema con estas funciones que pusiste? ¿no escriben esa marca?

Vi que buscas secuencialmente el archivo que quieres borrar en un ciclo for y te mueves en el archivo con estas instrucciones:
Código:
fseek(canal2,i*sizeof(struct venta),SEEK_SET);
fread(&v,sizeof(struct venta),1,canal2);
pero aquí la instrucción fseek no es necesaria, ya que fread incrementa el apuntador al archivo en cada iteración para apuntar al siguiente registro. En el ejemplo que te comento también busco secuencialmente el registro que quiero borrar y, al encontrarlo, uso la función fseek para regresar el apuntador del archivo a que apunte de nuevo al registro encontrado mandándole un número negativo en el segundo argumento de tamaño igual al registro, y poniendo en el tercer argumento el modificador SEEK_CUR, o sea, algo como esto
Código:
fseek (globfp, -1L * sizeof (a), SEEK_CUR);
fwrite (&a, sizeof (a), 1, globfp);
aunque la forma en que tú lo haces también me parece correcta y no creo que ahí esté el error.
  #3 (permalink)  
Antiguo 04/06/2007, 16:03
 
Fecha de Ingreso: junio-2007
Mensajes: 2
Antigüedad: 16 años, 11 meses
Puntos: 0
Re: Problema con busqueda en ficheros binarios en C

Mire el uso de fseek tienes razón sobra en el codigo, fread hace lo mismo.
Yo tambien pongo una marca cuando borro un venta o una persono. p.contro_alta o v.control_alta según sea.
Otra cosa no entiendo es cuando le pasas el segundo argumento por que multiplicas el tamaño de la estructura por -1L.

El codigo sigue sin funcionar.

Que estoy haciendo mal?
  #4 (permalink)  
Antiguo 04/06/2007, 21:51
 
Fecha de Ingreso: mayo-2006
Mensajes: 40
Antigüedad: 18 años
Puntos: 0
Re: Problema con busqueda en ficheros binarios en C

La función fseek mueve el apuntador al archivo de acuerdo al número de bytes que le des. Hay tres maneras de hacerlo, 2 absolutas y una relativa. Las dos absolutas son, ya sea a partir del comienzo del archivo (SEEK_SET) o del final (SEEK_END), y la relativa es de acuerdo a donde esté apuntando en ese momento el apuntador interno del archivo (SEEK_CUR). Esta constante se la das en el tercer parámetro de la función. El número de bytes para que se mueva el apuntador se lo das en el segundo argumento de la función como un valor long int, pero este puede ser negativo o positivo. Si le das un valor positivo el apuntador se moverá hacia adelante, y hacia atrás si le das un valor negativo.

En el ejemplo le doy un valor negativo para que se mueva hacia atrás tantos bytes como ocupa el registro del ejemplo, con esto el apuntador vuelve a apuntar al comienzo del registro que se quiere borrar.

De tu problema, pues lo único que te puedo decir es que trates de aislarlo de manera que sólo quede el código donde tienes el error y lo restante lo pongas en comentarios para que lo depures más fácilmente. Si te fijas el ejemplo que te di si borra bien los registros, entonces de ahí te puedes guiar para que funcione el tuyo.
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 18:38.