/* incasso.c
*
* Ricerca e visualizzazione di un incasso giornaliero.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_INCASSI 1000
#define NOME_FILE "incassi.txt"
struct data {
int giorno;
int mese;
int anno;
};
struct incasso {
struct data data_incasso;
float totale;
};
int leggi_incassi(char nome_file[], struct incasso vett[]) {
FILE *fp;
int dim = 0;
if ((fp = fopen(nome_file, "r")) == NULL)
return -1;
while (fscanf(fp, "%d%d%d%f", &vett[dim].data_incasso.giorno, &vett[dim].data_incasso.mese,
&vett[dim].data_incasso.anno, &vett[dim].totale) != EOF)
dim++;
fclose(fp);
return dim;
}
bool data_valida(int g, int m, int a) {
// Restituisce TRUE solo se i tre parametri di input rappresentano una data valida.
int giorni_in_mese[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Per semplicita' si accettano solo anni compresi tra 1950 e 2050
if (a < 1950 || a > 2050)
return false; // Anno non valido
if (m < 1 || m > 12)
return false; // Mese non valido
if (a % 4 == 0)
giorni_in_mese[1] = 29; // Correzione del numero di giorni di febbraio
// per gli anni bisestili
if (g < 1 || g >giorni_in_mese[m-1])
return false; // Giorno non valido
return true;
}
int confronta_date(struct data d1, struct data d2) {
// Funzione di confronto tra date rappresentate con numeri seriali
// La funzione restituisce un numero intero:
//
// Negativo se d1 < d2
// Uguale a zero se d1 = d2
// Positivo se d1 > d2
int seriale1, seriale2;
seriale1 = d1.anno * 10000 + d1.mese * 100 + d1.giorno;
seriale2 = d2.anno * 10000 + d2.mese * 100 + d2.giorno;
return seriale1 - seriale2;
}
int ricerca_incasso(struct incasso vett[], int dim, int giorno, int mese, int anno) {
int i_inf = 0;
int i_sup = dim -1;
int i_medio;
struct data data_input; // Utile per la funzione di confronto tra date
data_input.giorno = giorno;
data_input.mese = mese;
data_input.anno = anno;
while (i_inf <= i_sup) {
i_medio = (i_inf + i_sup) /2;
int ris_confronto;
ris_confronto = confronta_date(data_input, vett[i_medio].data_incasso);
if (ris_confronto == 0)
return i_medio;
else if (ris_confronto < 0)
i_sup = i_medio - 1;
else
i_inf = i_medio + 1;
}
return -1;
}
int main( void ) {
struct incasso tab[MAX_INCASSI];
int dim_tab;
struct data d;
int pos;
dim_tab = leggi_incassi(NOME_FILE, tab);
if (dim_tab < 0) {
printf("Errore nell'elaborazione del file di input.\n");
exit(1);
}
do {
printf("Inserire giorno mese e anno dell'incasso da ricercare: ");
scanf("%d%d%d", &d.giorno, &d.mese, &d.anno);
}
while (data_valida(d.giorno, d.mese, d.anno) == false);
pos = ricerca_incasso(tab, dim_tab, d.giorno, d.mese, d.anno);
if (pos < 0)
printf("Nessun incasso registrato in questa data.\n");
else
printf("Incasso del %d/%d/%d: %.2f Euro\n", d.giorno, d.mese, d.anno, tab[pos].totale);
return 0;
}