001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<string.h>
004: 
005: struct valuta{
006:   char nome[4];
007:   float tasso;
008:   int giorno, mese, anno;
009: };
010: 
011: int confrontapertasso(const void *, const void *);
012: int confrontaperdata(const void *, const void *);
013: 
014: int main(int argc, char **argv){
015: 
016:   char filename[10]; // sufficientemente lungo
017:   char code[4]; // per leggere nome valuta
018: 
019:   // CHIEDO CODICE VALUTA E COSTRUISCO NOME FILE
020:   printf("Inserisci il nome di una valuta: ");
021:   scanf("%s", code);
022: 
023:   strcpy(filename,code);
024:   strcat(filename,".txt"); // nel testo diceva .csv ma per errore ho fornito file con .txt
025: 
026:   // APRO FILE
027:   printf("Uso file %s\n", filename);
028:   FILE *fp=fopen(filename, "r");
029:   if(!fp)
030:   {
031:     perror("Errore");
032:     exit(EXIT_FAILURE);
033:   }
034: 
035:   struct valuta tmp; // temporaneo per leggere righe
036:   int righe=0;
037:   while(fscanf(fp,"  %[^,],%f,%d,%d,%d", tmp.nome, &tmp.tasso, &tmp.anno, &tmp.mese, &tmp.giorno)==5) righe++;
038:   printf("Il file contiene %d righe\n", righe); // XXX debug
039: 
040:   // ALLOCO ARRAY
041:   struct valuta *tassi=malloc(righe*sizeof(struct valuta));
042:   if(!tassi)
043:   {
044:     perror("malloc");
045:     exit(EXIT_FAILURE);
046:   }
047: 
048:   // RILEGGO FILE RIEMPENDO ARRAY
049:   fseek(fp, 0, SEEK_SET); // riparto dall'inizio del file
050:   int riga=0;
051:   while(fscanf(fp,"  %[^,],%f,%d,%d,%d", tassi[riga].nome, &tassi[riga].tasso, &tassi[riga].anno, &tassi[riga].mese, &tassi[riga].giorno)==5) 
052:   {
053:     // printf("Ho letto %s\t%f\t%02d/%02d/%04d\n", tassi[riga].nome, tassi[riga].tasso, tassi[riga].giorno, tassi[riga].mese, tassi[riga].anno); XXX
054:     // debug
055:     riga++;
056:   }
057:   fclose(fp);
058: 
059:   // ITERO CHIEDENDO ALL'UTENTE UN NUMERO
060:   int scelta;
061:   while(1)
062:   {
063:     printf("Inserisci scelta: ");
064:     scanf("%d", &scelta);
065:     switch(scelta)
066:     {
067:       case 0:
068:   printf("Ciao...\n");
069:   exit(EXIT_SUCCESS);
070:       case 1:
071:   {
072:     int anno, mese;
073:     float media=0;
074:     int giorni=0;
075: 
076:     printf("Calcolo tasso di cambio medio mensile\n");
077:     printf("Inserisci mese: ");
078:     scanf("%d", &mese);
079:     printf("Inserisci anno: ");
080:     scanf("%d", &anno);
081:     int i;
082:     for(i=0; i<righe; ++i)
083:     {
084:       if(mese==tassi[i].mese && anno==tassi[i].anno)
085:       {
086:         media += tassi[i].tasso;
087:         ++giorni;
088:       }
089:     }
090:     if(giorni)
091:       printf("Il tasso di cambio medio  %s/EUR per il mese %02d-%04d era %f\n", tassi[0].nome, mese, anno, media/giorni);
092:     else
093:       printf("Il tasso di cambio medio  %s/EUR per il mese %02d-%04d non e' calcolabile\n", tassi[0].nome, mese, anno);
094:   }
095:   break;
096:        case 2:
097:   {
098:     int anno, mese, giorno;
099:     char data[9]; // in programma sensato dimensione insufficiente!
100:     printf("Ricerca tasso giornaliero, inserisci una data nel formato ""ggmmaaaa"": ");
101:     scanf("%s", data);
102:     giorno=(data[0]-'0')*10 + (data[1]-'0'); // converto la stringa estraendo i numeri con una conversione da codice ASCII (metodo semplice ma un po' rozzo...)
103:     mese=(data[2]-'0')*10 + (data[3]-'0');
104:     anno=(data[4]-'0')*1000 + (data[5]-'0')*100 + (data[6]-'0')*10 +  (data[7]-'0');
105:     int i;
106:     for(i=0; i<righe; ++i)
107:     {
108:       if(giorno==tassi[i].giorno && mese==tassi[i].mese && anno==tassi[i].anno)
109:         printf("Il tasso di cambio %s/EUR per il giorno %02d-%02d-%04d era %f\n", tassi[0].nome, giorno, mese, anno, tassi[i].tasso);
110:     }
111:   }
112:   break;
113:        case 3:
114:   {
115:     int i;
116:     printf("Primi 10 valori letti:\n");
117:     for(i=0; i<10; ++i)
118:       printf("%2d: %s\t%f\t%02d/%02d/%04d\n", i+1, tassi[i].nome, tassi[i].tasso, tassi[i].giorno, tassi[i].mese, tassi[i].anno); 
119:   }
120:   break;
121:        case 4:
122:   printf("Ordino dati in base al tasso di cambio\n");
123:   qsort(tassi, righe, sizeof(struct valuta), confrontapertasso);
124:   break;
125:        case 5:
126:   printf("Ordino dati in base alla data\n");
127:   qsort(tassi, righe, sizeof(struct valuta), confrontaperdata);
128:   break;
129:        case 6:
130:   printf("Salvo su file ""out.dat""\n");
131:   fp=fopen("out.dat", "wb"); // per semplicita' salvo su file binario
132:   if(!fp)
133:   {
134:     perror("errore");
135:     exit(EXIT_FAILURE);
136:   }
137:   fwrite(tassi, sizeof(struct valuta), righe, fp);
138:   fclose(fp);
139:   break;
140:       default:
141:   printf("Errore in immissione scelta\n");
142:     }
143:   }
144:   return 0;
145: }
146: 
147: int confrontapertasso(const void *a, const void *b)
148: {
149:   const struct valuta *pa=a;
150:   const struct valuta *pb=b;
151:   if (pa->tasso>pb->tasso) return 1;
152:   if (pa->tasso<pb->tasso) return -1;
153:   return 0;
154:   
155: } 
156: 
157: int confrontaperdata(const void *a, const void *b)
158: {
159:   const struct valuta *pa=a;
160:   const struct valuta *pb=b;
161:   int dataa=pa->giorno+pa->mese*31+pa->anno*356;
162:   int datab=pb->giorno+pb->mese*31+pb->anno*356;
163:   // sicuramente dataa e datab sono crescenti inb base a giorno mese e anno
164:   return dataa-datab;
165: }
166: 
167: