[C] Errore fseek()

di il
22 risposte

22 Risposte - Pagina 2

  • Re: [C] Errore fseek()

    No, la lettura è corretta.
    Provo a spiegarmi un po' meglio..

    L'inizializzazione prende l'archivio pazienti, lo apre e cerca al suo interno (per poi caricare in memoria) tutti (e solo) i record relativi al medico che ha effettuato l'accesso.
    Quindi è normale che il numero di elementi in pazienti[] sia minore di quello nell'archivio (che genera 26 pazienti di test)...
  • Re: [C] Errore fseek()

    Il numero è minore ma il peso file è maggiore, come me lo spieghi?

    Errore mio, non sono 26 pazienti ma 25.
  • Re: [C] Errore fseek()

    Ok, penso di avere trovato il problema.
    Inserendo il controllo sull'indice dell'array, il programma smette di scrivere dati a caso nel file.
    Quindi evidentemente, sfonda l'array anche se non dovrebbe...
    Per un problema che si risolve se ne aprono cento ahahah
    Però almeno la povera fseek è stata discolpata..
  • Re: [C] Errore fseek()

    Te l'ho detto che lo sfonda. pazienti teneva dati casuali da un certo i in poi.
  • Re: [C] Errore fseek()

    Ok, c'è qualcosa che non capisco..
    Sto provando a fare delle prove riempiendo l'intero file di test con pazienti di uno stesso tipo di medico e, al primo fwrite, ho qualcosa di insolito...
    Già al primo record ho problemi: il programma esegue correttamente la fseek e riporta all'inizio del file il puntatore, poi esegue la fwrite.... ma, invece di avanzare di 9700 byte (cioè sizeof(Paziente) ) la posizione seguente è di soli 6684 byte più avanti... e ripete questa cosa anche per le seguenti fwrite...
    Non capisco X.x dim è 9700, perchè scrive solo 6684 bytes?
  • Re: [C] Errore fseek()

    Infatti ed ecco come l'ho risolto. fread non leggeva i 9700 bytes dopo la prima scrittura.
    
    int salva(Paziente pazienti[],int dimP,int medico)
    {
    	FILE *fp=NULL;
    	int i=0,pos,dim;
    	Paziente p = {0};
    
    	fpos_t temp = 0;
    	fp= fopen("pazienti","rb+");
    	if(fp==NULL)
    	{
    		printf("Errore nell'apertura dell'archivio pazienti\n");
    		return(0);
    	}   
    	setvbuf(fp,NULL,_IONBF,0);
    	dim=sizeof(Paziente); //Usata per il debug
    
    	do
    	{
    		fread(&p,sizeof(Paziente),1,fp);
    		dim=sizeof(Paziente); //Usata per il debug (controllavo che dim(p) fosse costante)
    		pos=ftell(fp); //Usata per il debug (verifica posizione settata da fseek)
    		if(p.medico_curante == medico) //medico è un numero che identifica il medico, e deve corrispondere a p.medico_curante
    		{
    			temp = pos - dim;
    			fsetpos(fp,&temp);
    			fwrite(&pazienti[i],sizeof(Paziente),1,fp);
    			i++;
    		}
    	}while(i < dimP && !feof(fp));
    	fclose(fp);
    	return(1);
    }
    
    Il problema è il buffer interno allocato per il file, di default mi pare che sia di 4096 bytes. Devi attivare la modalità no buffering così appena scrivi o leggi i dati vengono rispecchiati immediatamente. Dalle prove che ho fatto fread non sbaglia un colpo, legge sempre 9700 bytes.
  • Re: [C] Errore fseek()

    Versione finale.
    
    int salva(Paziente pazienti[],int dimP,int medico)
    {
    	FILE *fp=NULL;
    	int i=0,dim;
    	Paziente p = {0};
    
    	fpos_t temp = 0;
    	fp= fopen("pazienti","rb+");
    	if(fp==NULL)
    	{
    		printf("Errore nell'apertura dell'archivio pazienti\n");
    		return(0);
    	}   
    	setvbuf(fp,NULL,_IONBF,0);
    	dim=sizeof(Paziente); //Usata per il debug
    
    	do
    	{
    		fread(&p,sizeof(Paziente),1,fp);
    		fgetpos(fp,&temp); 
    		if(p.medico_curante == medico) 
    		{
    			temp -= dim;
    			fsetpos(fp,&temp);
    			fwrite(&pazienti[i],sizeof(Paziente),1,fp);
    			i++;
    		}
    	}while(i < dimP && !feof(fp));
    	fclose(fp);
    	return(1);
    }
    
  • Re: [C] Errore fseek()

    Grazie Milleeeeeeee!!!
    Pensavo fosse un problema simile, ma non sapevo che si potessero modificare la dimensione e le modalità di buffering della fwrite.
    Grazie mille dell'aiuto!!
Devi accedere o registrarti per scrivere nel forum
22 risposte