Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Funzione in C non funzionante?! Modifica struct salvata su file

    Ciao a tutti, nell'esercitazione scolastica che sto sviluppando (Linguaggio C in teoria, ma ai prof va bene che compiliamo codice misto C/C++) ho la necessità di "rimuovere logicamente" (tramite un campo nella struct) dei campi.

    Il codice che ho scritto:
    codice:
    struct movimento
    {
      char nome[42];
      char prestazione[42];
      char data[12];
      bool visible;
      bool ripetizione; /*se deve essere ripetuta*/
    };
    
    
    int removeAllMovementDate(char date[])
    {
        int max=julianDate(date); /*giorno giuliano della data inserita*/
        getchar();
        int now;
        int flag =0;
        char app[11];
        FILE *fp; 
        struct movimento rec;  
        fp=fopen("filemovimenti.dat", "r+b");/*Apertura file in modalita lettura e binario*/
        if(fp==NULL)
        {
            printf("\n Errore di apertura file \n");
            return(-1);
            getchar();
        }
        PuliziaBuffer();
        fread(&rec,sizeof(struct movimento),1,fp);    
        while(!feof(fp))
        {
            /*omettendo questa riga il problema non si presenta*/
            now=julianDate(app); /*giorno giuliano del movimento attuale*/
            if((rec.visible==true)&&(now<max))  /*se il movimento non è nascosto ed è precedente alla data*/
                {
                    rec.visible=false;    /*rendo il movimento non visibile */  
                    fseek(fp,-sizeof(struct movimento),SEEK_CUR);/*sposto il puntatore indietro di un record*/
                    fwrite(&rec,sizeof(struct movimento),1,fp);  /*e sovrascrivo*/
                     
                }       
            fread(&rec,sizeof(struct movimento),1,fp);
        }
        fclose(fp);
        printf("\n Sovrascrittura eseguita correttamente."); /*messaggio di avviso*/
        return(0);
    }
    La funzione julianDate è la seguente
    codice:
    int julianDate(char *data)
             { //restutisce quanti giorni sono passati dal 01/01/4713 a.C.            
                 char *cday,*cmonth,*cyear;
                 char separatore[]=" / - \ ";
                 cday=strtok(data,separatore);/*acquisico i numeri come stringhe*/
                 cmonth=strtok(NULL,separatore);
                 cyear=strtok(NULL,separatore);
                 int d =atoi(cday); /*converto in interi*/
                 int m = atoi(cmonth);
                 int y1 = atoi(cyear);
                 int a,y,l;
                 a=(14-m)/12;
                 y=y1+4800-a;
                 l=m+12*a-3;
                 return (d+(153*l+2)/5+365*y+y/4-y/100+y/400-32045);
             }
    Il problema è il seguente: andando a richiamare la funzione, va in loop nel ciclo
    codice:
    while(!feof(fp))
        {
            /*omettendo questa riga il problema non si presenta*/
            now=julianDate(app); /*giorno giuliano del movimento attuale*/
            if((rec.visible==true)&&(now<max))  /*se il movimento non è nascosto ed è precedente alla data*/
                {
                    rec.visible=false;    /*rendo il movimento non visibile */  
                    fseek(fp,-sizeof(struct movimento),SEEK_CUR);/*sposto il puntatore indietro di un record*/
                    fwrite(&rec,sizeof(struct movimento),1,fp);  /*e sovrascrivo*/
                     
                }       
            fread(&rec,sizeof(struct movimento),1,fp);
        }
    Il problema potrebbe potrebbe essere nella funzione julianDate? La utilizzo anche in altri ambiti ma non da problemi (ho notato che rovina il parametro passato).

    Grazie in anticipo per l'aiuto

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Non mi pare che assegni alcun valore a questa variabile app ... o mi sbaglio?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Scusate, andando ad inserire il commento mi si è cancellata la riga dove inserivo il valore nella variabile app
    L'istruzione era
    codice:
    strcpy(app,rec.data);
    Quindi il ciclo esatto è
    codice:
    while(!feof(fp))
        {
            strcpy(app,rec.data);
            /*omettendo questa riga il problema non si presenta*/
            now=julianDate(app);/*giorno giuliano del movimento attuale*/
            if((rec.visible==true)&&(now<max))/*se il movimento non è nascosto ed è precedente alla data*/
                {
                    rec.visible=false;/*rendo il movimento non visibile */  
                    fseek(fp,-sizeof(struct movimento),SEEK_CUR);/*sposto il puntatore indietro di un record*/
                    fwrite(&rec,sizeof(struct movimento),1,fp);/*e sovrascrivo*/
                     
                }       
            fread(&rec,sizeof(struct movimento),1,fp);
        }
    


    Ho anche notato che il file dove salvo la struttura diventa di dimensioni immani(da pochi KB a centinaia di MB)... può essere dovuto al fatto che il ciclo si ripeta all'infinito e quindi continua a scrivere su file?
    Non capisco perchè non esce mai dal ciclo, potrebbe esserci qualche problema di valore di fp?
    Il C, quant'è misterioso

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Dopo la fwrite prova ad inserire

    fseek(fp, 0, SEEK_CUR);
    Ultima modifica di oregon; 27-09-2015 a 16:45
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Grazie mille! Adesso non va in loop! Anche se a logica sembrerebbe inutile, funziona... sapresti dirmi come mai?

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Quando si utilizzano file binari in lettura/scrittura, è necessaria una fseek prima di un cambio di "verso". Ovvero, se stai leggendo e vuoi scrivere, devi fare prima una seek e così anche se hai scritto e vuoi tornare a leggere. Ecco perché è necessaria la fseek tra la fwrite e la fread anche se sembra non fare nulla.

    Nulla di misterioso (il C non è misterioso), se leggi la documentazione delle funzioni prima di usarle ... Ad esempio, in

    http://www.cplusplus.com/reference/cstdio/fseek/

    trovi questa cosa se leggi

    On streams open for update (read+write), a call to fseek allows to switch between reading and writing.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Grazie mille, non sapevo del fatto di dover fare la seek prima di dover invertire

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.