Salve a tutti, sono nuova qui sul forum e ho iniziato da poco a programmare in c e non ho ben chiaro come utilizzare vettori e puntatori in funzioni diverse. Vi scrivo qui il codice di un programma che mi da un errore di segmentazione sul quarto punto perché in realtà non ho ben capito come fare per passare ad una funzione un vettore che ho precedentemente riempito in un'altra funzione e sul quale voglio fare dei calcoli. Vi sarei grata se mi spiegaste come risolvere problemi di questo tipo. Grazie in anticipo. Il testo dell' esercizio è questo:
Un piccolo parco giochi a pagamento di una localita balneare gestisce il flusso di clienti fornendo un badge identi-
ficativo numerato a ciascun utente. La tariffazione avviene a tempo. A ciascun ingresso vengono pertanto associati
l’orario di ingresso e di uscita, oltre che la data. Tutti i dati vengono memorizzati in un file di testo. Questo e
organizzato in modo da memorizzare i dati dei singoli utenti su righe separate. Le righe del file hanno il seguente
formato:
gg/mm/aaaa nbadge h1:m1 h2:m2
dove:
• gg/mm/aaaa e la data d’ingresso; gg e il giorno (il primo giorno del mese e 1), mm e il mese (gennaio e il mese
numero 1, dicembre il 12) e aaaa è l’anno;
• nbadge e il numero identificativo del badge, un intero compreso tra 1 e 1000;
• h1:m1 e h2:m2 sono rispettivamente gli orari di ingresso e di uscita, nel formato ora:minuto; h1 e h2 rap-
presentano l’ora, e sono numeri interi compresi nell’intervallo [0, 23]; m1 e m2 rappresentano i minuti, e sono
numeri interi nell’intervallo [0, 59].
Lo stesso numero di badge può risultare associato a più ingressi. Come anticipato, la tariffazione avviene a tempo
secondo il seguente tariffario:
• fino a 20 minuti compresi: 3.5 euro;
• fino a 30 minuti compresi: 4 euro;
• fino a 45 minuti compresi: 4.5 euro;
• fino a 60 minuti compresi: 5.5 euro;
• oltre i 60 minuti: 7 euro (fino alla chiusura del parco).
Il parco apre tutti i giorni alle 19 e chiude alle 24. Il periodo di attività del parco va dal 1 aprile al 30 settembre.
Il file memorizza i dati relativi ad un solo anno di gestione del parco.
Richieste
Si scriva un programma che legga il file degli ingressi (il nome del file è ricevuto dalla riga di comando) e stampi a
video:
Richiesta 1. il numero d’ingressi presenti nel file usando il formato:
[INGRESSI]
10279
Richiesta 2. gli incassi effettuati nei mesi di apertura usando il formato:
[INCASSO_MENSILE]
Aprile 5975.00
Maggio 7496.50
Giugno 8611.50
Luglio 14113.50
Agosto 16417.00
Settembre 8611.50Richiesta 3. l’incasso totale effettuato nell’anno usando il formato:
[INCASSO_TOTALE]
61225.00
Richiesta 4. il mese con il maggior numero d’ingressi usando il formato:
[MESE_MAX_INGRESSI]
Agosto
#include <stdio.h>
#include <stdlib.h>
#define DIM 10
#define MAX 7
struct data {
int giorno, mese, anno;
};
struct ingresso{
struct data giorno;
int badge;
int permanenza; //nei punti successivi è questa la variabile che mi serve e non i due orari forniti dal file
double spesa;
};
int calcola_permanenza(int h1, int m1, int h2, int m2){
int orario1 = h1*60+m1; //calcolo il tempo di permanenza in minuti
int orario2 = h2*60+m2;
return orario2-orario1;
}
double calcola_spesa (int permanenza){
// non posso usare switch perchè sono dei range non delle uguaglianze
if(permanenza<=20)
return 3.5;
if(permanenza<=30)
return 4;
if(permanenza<=45)
return 4.5;
if(permanenza<=60)
return 5.5;
return 7;
}
struct ingresso * leggi_file(FILE *fp, int*size){
//creo un puntatore a intero size perche non so la dimensione del vettore che la funzione ritorna. la funzione non puo' ritornare sia il vettore che la sua dimensione quindi passo alla funzione l'indirizzo di size per poter cambiare anche la dimensione e ritornare solo il vettore. Quello che mi restituirà la funzione più precisamente è un puntatore al vettore di tipo struttura.
int dim=DIM;
int h1,m1,h2,m2;
int i=0;
char linea[1024];
struct ingresso *vet = malloc(sizeof(struct ingresso)*dim);
//vet e' composto da 10 elementi. E' un puntatore usato come elemento. Ricorda che la malloc restituisce sempre un puntatore al blocco di memoria allocata
if(vet==NULL){
*size = 0;
return NULL;
} //devo sempre controllare che il puntatore ritornato sia valido
while(fgets(linea,sizeof(linea),fp)!=NULL){
sscanf(linea, "%d/%d/%d %d %d:%d %d:%d", &(vet.giorno.giorno), &(vet.giorno.mese), &(vet.giorno.anno), &(vet.badge), &h1, &m1, &h2, &m2);
vet.permanenza = calcola_permanenza(h1,m1,h2,m2);
vet.spesa = calcola_spesa(vet.permanenza);
i++;
if(i>=dim){
dim = dim*2;
vet = realloc(vet, dim*sizeof(struct ingresso)); //vet è il puntatore del vettore che voglio riallocare
if(vet==NULL){
*size = i;
return vet;
}
}
//se metto una dimensione troppo grande mi faccio ritornare l'indice a partire dal quale il vettore non e' stato riempito. E poi la funzione ritorna comunque vet di dimensione dim.
}
*size = i;
return vet;
}
float *incasso_mensile (struct ingresso *vet,int size,float*incasso){
int i=0;
for(i=0; i<size; i++){
if(vet.giorno.mese==04){
incasso[0]+=vet.spesa;
}
if(vet.giorno.mese==05){
incasso[1]+=vet[i].spesa;
}
if(vet[i].giorno.mese==06){
incasso[2]+=vet[i].spesa;
}
if(vet[i].giorno.mese==07){
incasso[3]+=vet[i].spesa;
}
if(vet[i].giorno.mese==8){
incasso[4]+=vet[i].spesa;
}
if(vet[i].giorno.mese==9){
incasso[5]+=vet[i].spesa;
}
}
printf("Aprile %.2f\n",incasso[0]);
printf("Maggio %.2f\n",incasso[1]);
printf("Giugno %.2f\n",incasso[2]);
printf("Luglio %.2f\n",incasso[3]);
printf("Agosto %.2f\n",incasso[4]);
printf("Settembre %.2f\n",incasso[5]);
return incasso;
}
float incasso_tot(struct ingresso *vet, int size) {
int i;
float incasso;
for(i=0; i<size; i++){
incasso+=vet[i].spesa;
}
return incasso;
}
void max_ingressi(struct ingresso *vet, int size, float incassom[]){
int i;
float max=incassom[0];
for(i=1;i<size;i++)
{
if(incassom[i]>max)
max=incassom[i];
}
if (i==0)
printf("Aprile\n");
if (i==1)
printf("Maggio\n");
if (i==2)
printf("Giugno\n");
if (i==3)
printf("Luglio\n");
if (i==4)
printf("Agosto\n");
if (i==5)
printf("Settembre\n");
}
int main(int argc, char**argv){
int size=0;
float incassot;
struct ingresso * vett;
float incassom[MAX],*incasso;
incasso=&incassom[0];
if(argc=!2){
printf("Numero parametri errato\n");
return 1;
}
FILE* fin = fopen(argv[1],"r");
if(fin==NULL){
perror(argv[1]);
return 1;
}
vett = leggi_file(fin, &size); //gli passo l'indirizzo di size perchè nella funzione ho messo il puntatore
//poichè alla funzione ho passato il puntatore se adesso stampo size è già il valore corretto
printf("\n[INGRESSI]\n%d\n",size);
printf("\n[INCASSO_MENSILE]\n");
incasso_mensile(vett,size,&incassom[0]);
printf("\n[INCASSO_TOTALE]\n");
incassot=incasso_tot(vett,size);
printf("%.2f\n",incassot);
printf("\n[MAX_INGRESSI]\n");
max_ingressi(vett,size,&incassom[0]);
return 0;
}