250 lines
7.3 KiB
C
250 lines
7.3 KiB
C
// Laboratorio 1 - Esercizio 2
|
|
// Matteo Schiff - s295565
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#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 <data inizio> <data fine>'");
|
|
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 <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 <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 <data inizio> <data fine>'");
|
|
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 <codice tratta>'");
|
|
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, "./corse.txt")) {
|
|
return 1;
|
|
}
|
|
|
|
if (corse == NULL) {
|
|
return 1;
|
|
}
|
|
menuParola(corse, N);
|
|
|
|
return 0;
|
|
}
|