/* questo programma non e' commentato in quanto e' stato spiegato a lezione */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAXSTR 100
#define MAXNUM 80
#define ENOEL 1

#undef DEBUG

struct elemento{
 char nome[MAXSTR];
 char indirizzo[MAXSTR];
 unsigned long codice;
};

FILE *Fopen(const char *, const char *);
int leggielemento(struct elemento *, FILE *, char *, int);
int compara(const void *, const void *);

int main(int argc, char **argv){

FILE *mainstream;
struct elemento dati[MAXNUM], tmp;
int maxlen, ii=0, jj;
unsigned char inbuff[(maxlen=(sizeof(struct elemento)+2*sizeof(';')+sizeof('\n')+sizeof('\0')))];
char *nomifile[]={"primo.txt", "secondo.txt", NULL};

/* lettura file */
for(jj=0;nomifile[jj]!=NULL;++jj){
 mainstream=Fopen(nomifile[jj],"r");
 ii=0;
 while(1){
  if(leggielemento(&tmp, mainstream, inbuff, sizeof(inbuff)))
    break;
  else
    dati[ii++]=tmp;
  }
 fclose(mainstream);
}


/* ordinamento (NON era richiesto) */
qsort(dati,(size_t)ii,sizeof(struct elemento),compara);

/* output */
for(--ii;ii>=0;--ii)
 printf("%s - %s - %ld \n",dati[ii].nome,dati[ii].indirizzo,dati[ii].codice);
return 0;
}


int leggielemento(struct elemento *result, FILE *miofile, char *buffer, int len){
 char *p1,*p2;
 char lbuff[10];

 if((!fgets(buffer, len, miofile))||(!strchr(buffer,';')))
   return -ENOEL;
 for(p2=buffer;*p2==' ';++p2);
 for(p1=(result->nome);*p2!=';';++p2,++p1)*p1=*p2;
 for(--p1;*p1==' ';--p1);
 *++p1='\0';
 for(++p2;*p2==' ';++p2);
 for(p1=(result->indirizzo);*p2!=';';)*p1++=*p2++;
 for(--p1;*p1==' ';--p1);
 *++p1='\0';
 for(++p2;*p2==' ';++p2);
 for(p1=lbuff;((*p2!='\n')&&(*p2!=' '));)*p1++=*p2++;
 *p1='\0';
 result->codice=atol(lbuff);
 #ifdef DEBUG
  printf("ho letto %s -- %s -- %ld\n",result->nome,result->indirizzo,result->codice);
 #endif
 return 0;
}

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;
}


int compara(const void *a, const void *b){
	return ((((struct elemento*)a)->codice < ((struct elemento*)b)->codice)?1:-1);
}