// Laboratorio 6 - Esercizio 1 // Matteo Schiff - s295565 #include #include #include #include #include #define MAX_LEN 30 #define MAX_ROWS 1000 const int MAXL = 50; typedef struct Time { unsigned int hours; unsigned int minutes; unsigned int seconds; } time; typedef struct Date { unsigned int year; unsigned int month; unsigned int day; } date; typedef struct Corsa { char codice_tratta[MAX_LEN]; char partenza[MAX_LEN]; char destinazione[MAX_LEN]; date data; time ora_partenza; time ora_arrivo; unsigned int ritardo; } corsa; typedef enum { r_date, r_partenza, r_capolinea, r_ritardo, r_ritardo_tot, r_fine } t_comandi; char* toLower(char* s); t_comandi leggiComando(); int confrontaDate(date a, date b); void stampaCorsa(corsa corsa); void data(char * argomenti, corsa corse[MAX_ROWS], int N); void partenza(char * argomenti, corsa corse[MAX_ROWS], int N); void capolinea(char * argomenti, corsa corse[MAX_ROWS], int N); void ritardo(char * argomenti, corsa corse[MAX_ROWS], int N); void ritardoTot(char * argomenti, corsa corse[MAX_ROWS], int N); void menuParola (corsa corse[MAX_ROWS], int N); int loadFile(corsa corse[MAX_ROWS], int * N, char * filename); // Trasforma in lowercase tutti i caratteri di una stringa char* toLower(char* s) { for(char *p=s; *p; p++) *p=tolower(*p); return s; } t_comandi leggiComando() { t_comandi c; char cmd[MAXL]; char tabella[7][12] = { "date", "partenza", "capolinea", "ritardo", "ritardo_tot", "fine" }; printf("comando (date/partenza/capolinea"); printf("/ritardo/ritardo_tot/fine): "); scanf("%s",cmd); toLower(cmd); c=r_date; while(c<7 && strcmp(cmd,tabella[c])!=0) c++; return (c); } // restituisce true se la prima data è successiva o coincidente alla seconda int confrontaDate(date a, date b) { if (a.year > b.year) return true; else if (a.year < b.year) return false; if (a.month > b.month) return true; else if (a.month < b.month) return false; if (a.day >= b.day) return true; return false; } void stampaCorsa(corsa corsa) { printf(" - %s %s %s, data: %4u/%02u/%02u, ora di partenza: %02u:%02u:%02u, ora di arrivo: %02u:%02u:%02u, ritardo %d minuto\n", corsa.codice_tratta, corsa.partenza, corsa.destinazione, corsa.data.year, corsa.data.month, corsa.data.day, corsa.ora_partenza.hours, corsa.ora_partenza.minutes, corsa.ora_partenza.seconds, corsa.ora_arrivo.hours, corsa.ora_arrivo.minutes, corsa.ora_arrivo.seconds, corsa.ritardo); } void data(char * argomenti, corsa corse[MAX_ROWS], int N) { date data_inizio, data_fine; if (sscanf(argomenti, " %4u/%2u/%2u %4u/%2u/%2u", &data_inizio.year, &data_inizio.month, &data_inizio.day, &data_fine.year, &data_fine.month, &data_fine.day) != 6) { puts("Date non valide. La sintassi è 'date '"); return; } puts("Elenco corse con partenza compresa nell'intervallo specificato:\n"); for (int i = 0; i < N; i++) { if (confrontaDate(corse[i].data, data_inizio) && confrontaDate(data_fine, corse[i].data)) { stampaCorsa(corse[i]); } } } void partenza(char * argomenti, corsa corse[MAX_ROWS], int N) { char partenza[30]; if (sscanf(argomenti, " %30s", partenza) != 1) { puts("Partenza non valida. La sintassi è 'partenza '"); return; } printf("Elenco corse con partenza da %s:\n", partenza); for (int i = 0; i < N; i++) { if (strcmp(partenza, corse[i].partenza) == 0) { stampaCorsa(corse[i]); } } } void capolinea(char * argomenti, corsa corse[MAX_ROWS], int N) { char capolinea[30]; if (sscanf(argomenti, " %30s", capolinea) != 1) { puts("Capolinea non valido. La sintassi è 'capolinea '"); return; } printf("Elenco corse con capolinea da %s:\n", capolinea); for (int i = 0; i < N; i++) { if (strcmp(capolinea, corse[i].destinazione) == 0) { stampaCorsa(corse[i]); } } } void ritardo(char * argomenti, corsa corse[MAX_ROWS], int N) { date data_inizio, data_fine; if (sscanf(argomenti, " %4u/%2u/%2u %4u/%2u/%2u", &data_inizio.year, &data_inizio.month, &data_inizio.day, &data_fine.year, &data_fine.month, &data_fine.day) != 6) { puts("Date non valide. La sintassi è 'date '"); return; } puts("Eleco corse con ritardo nell'intervallo di date specificato:\n"); for (int i = 0; i < N; i++) { if (confrontaDate(corse[i].data, data_inizio) && confrontaDate(data_fine, corse[i].data) && corse[i].ritardo > 0) { stampaCorsa(corse[i]); } } } void ritardoTot(char * argomenti, corsa corse[MAX_ROWS], int N) { char codice_tratta[30]; if (sscanf(argomenti, " %30s", codice_tratta) != 1) { puts("Codice di tratta non valido. La sintassi è 'ritardo_tot '"); return; } unsigned int sum = 0; for (int i = 0; i < N; i++) { if (strcmp(codice_tratta, corse[i].codice_tratta) == 0) { sum += corse[i].ritardo; } } printf("Il ritardo complessivo accumulato sulla tratta %s è pari a %u minuti.\n", codice_tratta, sum); } void menuParola (corsa corse[MAX_ROWS], int N) { t_comandi comando; char argomenti[MAXL]; int i, continua=1; while (continua) { comando = leggiComando(); fgets(argomenti,MAXL,stdin); /* resto della riga */ switch (comando) { case r_date: data(argomenti, corse, N); break; case r_partenza: partenza(argomenti, corse, N); break; case r_capolinea: capolinea(argomenti, corse, N); break; case r_ritardo: ritardo(argomenti, corse, N); break; case r_ritardo_tot: ritardoTot(argomenti, corse, N); break; case r_fine: continua = 0; break; default: puts("Comando non valido\n"); } } } int loadFile(corsa corse[MAX_ROWS], int * N, char * filename) { FILE *fp_read; unsigned int lines, i; if ((fp_read = fopen(filename, "r")) == NULL) { puts("Impossibile aprire il file"); return 1; } fscanf(fp_read, "%u\n", &lines); if (lines > MAX_ROWS) { fclose(fp_read); return 1; } for (i = 0; i < lines; i++) { int num_read = fscanf(fp_read, "%30s %30s %30s %4u/%2u/%2u %2u:%2u:%2u %2u:%2u:%2u %u\n", corse[i].codice_tratta, corse[i].partenza, corse[i].destinazione, &corse[i].data.year, &corse[i].data.month, &corse[i].data.day, &corse[i].ora_partenza.hours, &corse[i].ora_partenza.minutes, &corse[i].ora_partenza.seconds, &corse[i].ora_arrivo.hours, &corse[i].ora_arrivo.minutes, &corse[i].ora_arrivo.seconds, &corse[i].ritardo); if (num_read != 13) { // la stringa è mal formattata printf("File non formattato correttamente. Errore a linea %d\n", i+1); fclose(fp_read); return 1; } } fclose(fp_read); *N = i; return 0; } int main() { int N; corsa corse[MAX_ROWS]; if (loadFile(corse, &N, "./log.txt")) { return 1; } if (corse == NULL) { return 1; } menuParola(corse, N); return 0; }