File binario

di il
8 risposte

File binario

Salve, ho realizzato un programma dove ho inserito le funzioni ScrivereFile e CalcolareDimensioneFile.
Ho dovuto realizzare la funzione ScrivereFile perchè nella traccia dell'esercizio c'è scritto di considerare di avere un file binario scritto nel seguente modo:
139 13 3
123 24 3
94 15 3
133 21 2
118 22 4
116 24 4
Queste sono le funzioni:
void ScrivereFile(FILE **fd, char nomefile[]){
	int buffer[] = {139,13,3,123,24,3,94,15,3,133,21,2,118,22,4,116,24,4};

	fwrite(buffer, sizeof(int), 18, *fd);
	fseek(*fd, 0, SEEK_SET);

	return;
}

void CalcolareDimensioneFile(FILE *fp, VettoreDati *d){
	int vett[3];
	int res;
	int cont = 0;
	int i = 0;

	while(1){
		res = fread(vett, sizeof(int), 3, fp);
        /*test*/printf("%d %d %d\n",vett[i], vett[i + 1], vett[i + 2]);
		cont++;
		if (res != 3){
			cont--;
			break;
		}
	}

	d->dimensione = cont;
	printf("dim: %d \n",d->dimensione);
	fseek(fp, 0, SEEK_SET);

	return;
}
Perchè quando mi stampa la dimensione dice che dim è uguale a 341?
Il risultato corretto dovrebbe essere 6 (ovvero il numero di triple presenti nel file).

8 Risposte

  • Re: File binario

    A me dà 6 ma ho modificato il tuo codice.

    Nella prima funzione non usi il nomefile e non si capisce perché usi un doppio puntatore.

    Nella seconda funzione, non uso il secondo parametro perché non conosco la struttura che usi.

    Manca totalmente il main.
  • Re: File binario

    Effettivamente il doppio puntatore e il nomefile non servono, questo é il codice completo.
    /*Un file binario contiene il numero di presenze degli studenti alle lezioni di un corso.
    Ogni elemento del file contiene 3 valori. Come esempio si consideri il seguente file.
    139 13 3
    123 24 3
    94 15 3
    133 21 2
    118 22 4
    116 24 4
    Il primo valore rappresenta il numero di studenti presenti, il secondo e il terzo rispettivamente giorno e
    mese della lezione (si suppone che le lezioni abbiano luogo tutte nello stesso anno solare).
    Si noti che il file non e’ ordinato.
    Si scriva una funzione che prende come parametro il nome del file (sicuramente presente su disco) e
    restituisce il numero di studenti della prima lezione del corso (cioè la lezione la cui data è minima
    tra quelle presenti nel file). Nell’esempio la funzione deve restituire 133, cioè il numero di presenze
    del 21 febbraio.
    La funzione deve restituire 0 nel caso che qualche data abbia contenuto non valido: valore del mese maggiore
    di 12, oppure valore del giorno maggiore del numero di giorni del mese (ad esempio 23/14, 31/06).*/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define DIM 1000
    #define LEN 3
    #define MESI 12
    
    typedef struct{
    	int presenze;
    	int giorno;
    	int mese;
    }Dati;
    
    typedef struct{
    	Dati *elenco;
    	int dimensione;
    }VettoreDati;
    
    typedef struct{
    	int giornidelmese[MESI];
    }VerificaGiorni;
    
    void ScrivereFile(FILE *fd);
    int NumeroStudentiPrimaLezione(char nomefile[], VettoreDati *p, VerificaGiorni calendario);
    int LeggereFile(FILE **fp, char nomefile[]);
    void CalcolareDimensioneFile(FILE *fp, VettoreDati *d);
    void AllocareMemoriaElenco(Dati **elenco, int dim);
    int VerificaCorrettezzaGiornoEMese(int giorno, int mese, VerificaGiorni calendario);
    int TrovareNumeriStudentiPrimaLezione(VettoreDati *p);
    
    int main(void){
    	char nomefile[DIM];
    	int num;
    	VettoreDati tabulato;
    	VerificaGiorni calendario = {{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
    
    	strcpy(nomefile, "dati.dat");
    
    	num = NumeroStudentiPrimaLezione(nomefile, &tabulato, calendario); /*restituisce il numero di studenti della prima lezione del corso,
    													restituisce 0 nel caso in cui qualche data abbia contenuto non valido*/
    
    	printf("numero presenze della prima lezione> %d\n",num);
    
    	system("pause");
    	return 0;
    }
    
    int NumeroStudentiPrimaLezione(char nomefile[], VettoreDati *p, VerificaGiorni calendario){
    	FILE *fp;
    	int esito;
    	int vett[LEN];
    	int res;
    	int i = 0;
    	int j = 0;
    	int num;
    	int k = 1;
    
    	esito = LeggereFile(&fp, nomefile);
    	printf("esito> %d\n",esito);
    
    	if (esito == 0){
    		printf("return");
    		return esito;
    	}
    
    	ScrivereFile(fp); //necessario per svolgere la traccia
    
    
    	CalcolareDimensioneFile(fp, p);
    	AllocareMemoriaElenco(&p->elenco, p->dimensione);
    	printf("dim: %d \n",p->dimensione);
    
    	do{
    		j = 0;
    		res = fread(vett, sizeof(int), 3, fp);
    		printf("res> %d\n",res);
    		if (res == LEN){
    			(p->elenco + i)->presenze = vett[j];
    			printf("presenze %d\n",(p->elenco + i)->presenze);
    			(p->elenco + i)->giorno = vett[j + 1];
    			printf("giorno %d\n",(p->elenco + i)->giorno);
    			(p->elenco + i)->mese = vett[j + 2];
    			printf("mese %d\n",(p->elenco + i)->mese);
    			k = VerificaCorrettezzaGiornoEMese((p->elenco + i)->giorno, (p->elenco + i)->mese, calendario);
    			printf("k> %d\n",k);
    			i++;
    		}
    	}while (res == LEN && k == 1);
    
    	fseek(fp, 0, SEEK_SET);
    
    	num = TrovareNumeriStudentiPrimaLezione(p);
    
    	return num;
    }
    
    int LeggereFile(FILE **fp, char nomefile[]){
    	int i = 1;
    	if ((*fp = fopen(nomefile, "r+")) == NULL){
    		i = 0;
    	}
    
    	return i;
    }
    
    void ScrivereFile(FILE *fd){
    	int buffer[] = {139,13,3,123,24,3,94,15,3,133,21,2,118,22,4,116,24,4};
    
    	fwrite(buffer, sizeof(int), 18, fd);
    	fseek(fd, 0, SEEK_SET);
    
    	return;
    }
    
    void CalcolareDimensioneFile(FILE *fp, VettoreDati *d){
    	int vett[LEN];
    	int res;
    	int cont = 0;
    	int i = 0;
    
    	while(1){
    		res = fread(vett, sizeof(int), 3, fp);
    		printf("%d %d %d\n",vett[i], vett[i + 1], vett[i + 2]);
    		cont++;
    		if (res != LEN){
    			cont--;
    			break;
    		}
    	}
    
    	d->dimensione = cont;
    	printf("1dim: %d \n",d->dimensione);
    	fseek(fp, 0, SEEK_SET);
    
    	return;
    }
    
    void AllocareMemoriaElenco(Dati **elenco, int dim){
    	*elenco = malloc (dim * sizeof(Dati));
    
    	return;
    }
    int VerificaCorrettezzaGiornoEMese(int giorno, int mese, VerificaGiorni calendario){
    	int i = 1;
    	if (mese > 12 || mese < 1){
    		return 0;
    	}
    	if ((giorno > *(calendario.giornidelmese + mese - 1)) || giorno < 1){
    		return 0;
    	}
    
    	return i;
    }
    
    int TrovareNumeriStudentiPrimaLezione(VettoreDati *p){
    	int i = 0;
    	int j;
    	int min = (p->elenco + i)->mese;
    
    	while (i < MESI){
    		if (min > (p->elenco + i)->mese){
    			min = (p->elenco + i)->mese;
    			j = i;
    		}
    		i++;
    	}
    
    	return (p->elenco + j)->presenze;
    }
    
  • Re: File binario

    La fopen per un file binario deve includere la b, quindi

    "rb+"

    Ma attenzione, con "rb+" il file deve esistere per essere aperto. Per crearlo deve essere "wb+"
  • Re: File binario

    Ho provato a scrivere rb+ ma continua a stampare dim> 341.
    Inoltre questa printf
    printf("%d %d %d\n",vett, vett[i + 1], vett[i + 2]);
    dopo aver stampato i valori presenti nel file, mi stampa tanti zeri che non dovrebbe stampare.
  • Re: File binario

    Il file con rb+ deve esistere. Se non esiste va creato con wb. Il codice che hai postato apre prima il file ma se non esiste si ferma.

    Quale ambiente e compilatore usi?
  • Re: File binario

    
    #define MESI 12
    
    typedef struct{
    	int giornidelmese[MESI];
    }VerificaGiorni;
    
    int main(void){
    	VerificaGiorni calendario = {{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
    
    Questi codice è "boilerplate"

    È meglio scrivere (non siamo in Java che deve essere tutto incapsulato)
    
    const int giornidelmese[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    int main(void){
    
    Ricordati che il boilerplate ha un costo: quando commetti un piccolo errore, passi molto tempo ad individuarlo.
  • Re: File binario

    Il file binario l'ho creato a mano, ovvero su eclipse ho creato un file con estensione .dat, é sbagliato?
  • Re: File binario

    Apri il file con un editor esadecimale e vedi cosa hai creato
Devi accedere o registrarti per scrivere nel forum
8 risposte