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: