Retroceder   Foros del Web > Temas generales de computación > Programación > C/C++

Respuesta
 
Herramientas Desplegado
Antiguo 01-jun-2007, 12:33   #1 (permalink)
neyboll no se puede cailificar en este momento
 
Fecha de Ingreso: junio-2007
Mensajes: 2
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-jun-2007 a las 19:46.
neyboll está desconectado   Responder Citando
Antiguo 01-jun-2007, 15:05   #2 (permalink)
pitukilloloco ha deshabilitado el karma
 
Fecha de Ingreso: mayo-2006
Mensajes: 40
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.
pitukilloloco está desconectado   Responder Citando
Antiguo 04-jun-2007, 16:03   #3 (permalink)
neyboll no se puede cailificar en este momento
 
Fecha de Ingreso: junio-2007
Mensajes: 2
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?
neyboll está desconectado   Responder Citando
Antiguo 04-jun-2007, 21:51   #4 (permalink)
pitukilloloco ha deshabilitado el karma
 
Fecha de Ingreso: mayo-2006
Mensajes: 40
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.
pitukilloloco está desconectado   Responder Citando
Respuesta

No hay votos aún.


Herramientas
Desplegado

Normas de Publicación
No puedes crear nuevos temas
No puedes responder temas
No puedes subir archivos adjuntos
No puedes editar tus mensajes

BB code is Activado
Caritas están Activado
[IMG] está Activado
Código HTML está Desactivado


La Zona horaria es GMT -6. Ahora son las 02:43.


Message Board Statistics

LinkBacks Enabled by vBSEO 3.1.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93