001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<math.h>
004: #include<string.h>
005: 
006: // costanti
007: const char *nomimesi[]        = { "Vendemmiaio", "Brumaio","Frimaio","Nevoso","Piovoso","Ventoso","Germile","Florile","Pratile","Messidoro","Termidoro","Fruttidoro","Giorni Complementari" };
008: const char *nomigiornicompl[] = { "Giorno della Virtu'","Giorno del Genio","Giorno del Lavoro","Giorno dell'Opinione","Giorno delle Ricompense","Giorno della Rivoluzione" };
009: 
010: 
011: // FUNZIONI PREDEFINITE
012: 
013: // restituisce giorni passati dal 22/09/1792, numero da 0 a salire
014: unsigned int giorni(unsigned int g, unsigned int m, unsigned int a);
015: 
016: // converte anno da formato decimale a formato con cifre romane (uso solo cosmatico a vostra scelta)
017: void romano(int anno, char *out);         
018: 
019: // FUNZIONE DA DEFINIRE COME DA PROTOTIPO SEGUENTE
020: int checkdata(unsigned int g, unsigned int m, unsigned int a);
021: 
022: 
023: int main(int argc, char **argv){
024: 
025:   // variabili per lettura da file
026:   unsigned int giorno, mese, anno;
027:   char descriz[201]; // 200 caratteri max + 1 carattere per terminatore stringa
028: 
029:   // apro il file in input
030:   FILE *date = fopen("date.txt", "r");
031:   if(!date)
032:   {
033:     perror("");
034:     exit(EXIT_FAILURE);
035:   }
036: 
037:   // apro il file in output (punto 2.e, ma lo devo fare qui)
038:   FILE *fout = fopen("rivcal.txt", "w");
039:   if(!fout)
040:   {
041:     perror("");
042:     exit(EXIT_FAILURE);
043:   }
044: 
045:   // ciclo di lettura riga per riga
046:   while(fscanf(date, "%u/%u/%u;%[^\n]", &giorno, &mese, &anno, descriz) == 4)
047:   {
048:     printf("Provo a convertire la data %u.%u.%u\n", giorno, mese, anno);
049:     // 2.a invoco la funzione checkdata()
050:     int data_valida = checkdata(giorno, mese, anno);
051: 
052:     // se la data e' antecedente il 22/09/1792 non proseguo
053:     if(!data_valida)
054:     {
055:       printf(" data antecedente al 22 settembre 1792, la ignoro\n");
056:       continue;
057:     }
058: 
059:     // 2.b calcolo i giorni passati dal 22 settembre 1792
060:     int giornitot = giorni(giorno, mese, anno);
061: 
062:     // 2.c calcolo anno sottraendo dal numero dei giorni 365 o 366 a seconda dell'anno
063:     int franno     = 1;    // contatore anno
064:     int giornianno = 365;  // giorni dell'anno in esame
065:     while(giornitot >= giornianno)
066:     {
067:       giornitot -= giornianno;
068:       ++franno;
069:       // if(!(franno%4))
070:       if(!(franno%4) && (franno%128))                   // modificato per punto 3
071:   giornianno = 366;
072:       else
073:   giornianno = 365;
074:     }
075:     //printf("DEBUG: ho ottenuto %d come anno rivoluzionario e mi restano %d giorni\n", franno, giornitot);
076: 
077:     // 2.d calcolo mese e giorni
078:     int frmese    = giornitot/30;      // indice tra 0 e 11 (ma viene 12 per i giorni complementari)
079:     int frgiorno  = giornitot%30 + 1;  // tra 0 e 29 ma lo aggiusto ai fini stampa
080: 
081:     // 2.c salvo nel file in uscita
082:     // mi avvalgo della funzione romano() per convertire la rappresentazione dell'anno nel sistema di numerazione romano
083:     // stampero' quindi CCXXXIV invece di 234
084:     // non era comunque richiesto
085:     char frromano[100];  // sto largo
086:     romano(franno, frromano);
087:     if(frmese < 12)
088:     {
089:       printf(" La data convertita e' %d %s dell'anno %s, la riporto sul file di output\n", frgiorno, nomimesi[frmese], frromano);
090:       fprintf(fout,"%d %s dell'anno %s: %s\n", frgiorno, nomimesi[frmese], frromano, descriz);
091:     }
092:     else
093:     {
094:       printf(" La data convertita e' ,%s dell'anno %s la riporto sul file di output\n", nomigiornicompl[frgiorno - 1], frromano);
095:       fprintf(fout,"%s dell'anno %s: %s\n", nomigiornicompl[frgiorno - 1], frromano, descriz);
096:     }
097:   }
098: 
099:   return 0;
100: }
101: 
102: 
103: int checkdata(unsigned int g, unsigned int m, unsigned int a)
104: {
105:   if (a < 1792 || (a == 1792 && m < 9) || (a == 1792 && m ==9 && g < 22))
106:     return 0;
107:   return 1;
108: }
109: 
110: 
111: /**********************************************************
112:   NON MODIFICARE AL DI SOTTO DI QUESTA LINEA
113:  **********************************************************/
114: 
115: 
116: unsigned int giorni(unsigned int g, unsigned int m, unsigned int a)
117: {
118:   m = (m + 9) % 12;
119:   a = a - m / 10;
120:   int __part1 = a * 0x16D;               /* 0x16D == 365 */
121:   int __part2 = a / 4 - a / 100 + a / 400;
122:   int __part3 = (m * 306 + 5) / 10;
123:   int __sum   = __part1 + __part2 + __part3 + g - 1 - 0x9FD80;
124:   return (unsigned int)(__sum < 0 ? -__sum : __sum);
125: }
126: 
127: void romano(int anno, char *out) 
128: {
129:   struct 
130:   {
131:     int val;
132:     const char *sym;
133:   } map[] = { {1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"},  {90, "XC"},  {50, "L"},  {40, "XL"}, {10, "X"},   {9, "IX"},   {5, "V"},   {4, "IV"}, {1, "I"} };
134: 
135:   out[0] = '\0';  /* inizializza stringa vuota */
136: 
137:   for (int i = 0; i < 13; i++) {
138:     while (anno >= map[i].val) {
139:       strcat(out, map[i].sym);
140:       anno -= map[i].val;
141:     }
142:   }
143: }
144: 
145: