001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<time.h>
004: 
005: #define MAX_EXP 20
006: 
007: 
008: int  *leggi_polinomio(FILE *);
009: void stampa_polinomio(int *);
010: 
011: int main(int argc, char **argv){
012:   srand(time(0));
013: 
014:   int **polinomi = NULL; // array bidimensionale di int che mi permette di memorizzare i vari polinomi
015:   int n_polinomi = 0;    // numero dei polinomi, usato anche per la gestione dell'allocazione dinamica del precedente array
016: 
017:   FILE *fp = fopen("polinomi.txt", "r");
018:   if(!fp)
019:   {
020:     perror("");
021:     exit(EXIT_FAILURE);
022:   }
023: 
024:   int *p; // variabile d'appoggio per contenere i dati di un singolo polinomio
025:   while((p = leggi_polinomio(fp)))
026:   {
027:     // aggiorno numero di polinomi letti, allargo array di array con realloc() e memorizzo polinomio letto
028:     ++n_polinomi;
029:     polinomi = realloc(polinomi, sizeof(int *)*n_polinomi);
030:     polinomi[n_polinomi - 1] = p;
031:   }
032: 
033:   printf("Ho letto %d polinomi\n", n_polinomi);
034: 
035:   while(1) // l'iterativamente nel testo
036:   {
037:     // seleziono due polinomi a caso
038:     int p1_ind = rand()%n_polinomi;
039:     int p2_ind = rand()%n_polinomi;
040: 
041:     printf("Calcolo la somma dei polinomi #%d e #%d\n", p1_ind, p2_ind);
042: 
043:     // preparo array che sia somma
044:     int p_sum[MAX_EXP + 1]; // inutile qui allocazione dinamica
045: 
046:     printf("P1:    ");
047:     stampa_polinomio(polinomi[p1_ind]);
048:     printf("\n");
049: 
050:     printf("P2:    ");
051:     stampa_polinomio(polinomi[p2_ind]);
052:     printf("\n");
053: 
054:     // elemento per elemento sommo
055:     for(int i = 0; i <= MAX_EXP; ++i)
056:       p_sum[i] = polinomi[p1_ind][i] + polinomi[p2_ind][i];
057: 
058:     printf("SOMMA: ");
059:     stampa_polinomio(p_sum);
060:     printf("\n");
061: 
062:     getchar(); // richiedo pressione invio per continuare
063:   }
064: 
065:   return 0;
066: }
067: 
068: // funzione che legge e alloca opportuno array di int letti dalla prossima riga
069: // si basa sul fatto che su ciascuna riga c'e' sicuramente almeno una copia di numeri e che subito dopo l'ultimo
070: // c'e' un "a capo". Leggo i numeri a coppia e il carattere successivo. Se il carattere successivo non e' uno spazio allora
071: // sono arrivato a fine riga
072: // come capisco se il file e' finito? semplicemente NON riesco a leggere una coppia di numeri e allora esco restituendo NULL
073: int *leggi_polinomio(FILE *f)
074: {
075:   char c;  // usato per capire se arrivo a fine riga o meno
076: 
077:   int *polinomio = calloc(sizeof(int), MAX_EXP + 1); // array allocato dinamicamente ma di dimensione fissa per memorizzare il singolo polinomio
078:   // l'indice mi indica l'esponente e il contenuto il relatiovo coefficiente
079:   // uso calloc() in maniera che inizialmente contenfa solo zeri
080: 
081:   do{
082:     int coeff, base; // per memorizzare le varie coppie
083: 
084:     int check = fscanf(f, "%d %d", &coeff, &base); // provo a leggere due numeri e memorizzo risultato fscanf() in check
085:     if(check != 2) return NULL; // se non ho letto due numeri vuol dire che sono arrivato a fine file ed esco
086:     polinomio[base] = coeff; // l'indice mi indica l'esponente, il contenuto dell'elemento il coefficiente
087: 
088:     c = fgetc(f); // leggo carattere dopo il secondo numero letto, se e' uno spazio ci sono ancora numeri sulla riga, altrimenti ho finito il polinomio
089:   }
090:   while(c == ' ');
091: 
092:   return polinomio;
093: }
094: 
095: // funzione che stampa un singolo polinomio nel formato richiesto dal testo
096: void stampa_polinomio(int *p)
097: {
098:   for(int i=MAX_EXP; i>0; --i)
099:   {
100:     if(p[i])
101:       printf("%+dx^%d", p[i], i);
102:   }
103: 
104:   // il termine noto lo considero a parte non dovendo stampare la 'x'
105:   if(p[0])
106:     printf("%+d", p[0]); 
107: }
108: 
109: