/* possibile soluzione all'esame del 9 giugno 2001 */
#include<stdio.h>
#include<stdlib.h>

/* lunghezza massima nomi file */
#define ML 255
/* lunghezza buffer */
#define BL 5


/* prototipi funzioni */
void *Realloc(void *, size_t);
FILE *Fopen(const char *, const char *);
void leggi_nome(char *);
int notAZ(int a);

int main(int argc, char **argv){
  FILE *f1, *f2; /* file in lettura */
  char fn1[ML], fn2[ML]; /* nomi file */
  int b1, b2; /* buffer di lettura */
  char c; /* valore da memorizzare */
  int n=0; /* numero caratteri letti */
  char *ris=NULL; /* vettore risultato */
  int d=0; /* dimensione buffer/BL */

  /* chiedo i nomi dei file */
  printf("Inserisci il nome del primo file:   ");
  leggi_nome(fn1);
  printf("inserisci il nome del secondo file: ");
  leggi_nome(fn2);

  /* apro i file */
  f1=Fopen(fn1,"r");
  f2=Fopen(fn2,"r");

  /* leggo i file carattere a carattere, calcolo la somma
   * e la memorizzo in un buffer allocato dinameicamente */
  while(1){
    /* leggo due caratteri */
    b1=getc(f1);
    if(notAZ(b1)) /* se fine file o carattere invalido esco */
      break;
    b2=getc(f2);
    if(notAZ(b2))
      break;
    ++n; /* aggiorno numero caratteri letti */
    /* calcolo il valore */
    c=(((char)b1-'A')+((char)b2-'A'))%('Z'-'A')+'A';
    /* controllo di avere spazio per la memorizzazione */
    if(d*BL<(n+1)){ 
      ++d; 
      ris=Realloc(ris,d*BL); /* cambio le dimensioni del buffer di letturai */
    }
    ris[n-1]=c;
  }

  /* chiudo i file */
  fclose(f1);
  fclose(f2);

  /* termino la stringa */
  ris[n]='\0';

  /* stampo il risultato a video */
  printf("%s\n",ris);

  /* libero la memoria */
  free(ris);

  return EXIT_SUCCESS; /* codice di uscita senza errori */
}

/* controlla la validita' del carattere letto,
 * chiaramente funziona anche con EOF */
int notAZ(int a){
  if((a<'A')||(a>'Z'))
    return 1;
  return 0;
}


/* legge una stringa di max ML e la infila all'indirizzo dato*/
void leggi_nome(char *a){
  fgets(a,ML-1,stdin);
  /* fgets purtroppo infila nella stringa letta anche l'acapo */
  a[strlen(a)-1]='\0'; /* elimino lo '\n' */
  /* controllo che cio' che sia stato inserito qualcosa*/
  if(!strlen(a)){
    fprintf(stderr,"Nome file nullo! \n");
    exit(EXIT_FAILURE);
  }
}

/* solite procedure utilizzate durante il corso */
/*************************************************************************/

void *Realloc(void *ptr, size_t size)
{
 void *genericp;
 if((genericp=realloc(ptr, size))==NULL)
  {
   perror("Realloc");
   exit(EXIT_FAILURE);
  }
  return genericp;
}

/*************************************************************************/

FILE *Fopen(const char *nome, const char *modo)
{
FILE *tmp;

 if((tmp=fopen(nome, modo))==NULL)
  {
   fprintf(stderr, "Non riesco ad aprire il file %s in maniera %s\n",nome, modo);
   perror("Fopen");
   exit(1);
  }
 return tmp;
}