/* Soluzione proposta da: Perazzolo Giorgio */


#include <stdio.h>

#include <string.h>

#include <stdlib.h>


#define LEN 30


/*Dichiaro la struttura dati */
struct num{
	   int numero;
	   struct num *next;
	   };

/*Prototipi*/
void carica(struct num *list, struct num *nuovo);
void salva_stampa(struct num *a, struct num *b);
struct num *iniz(void);
void ordina(struct num *nuovo, struct num *ordine);

main()
{
	struct num *lista;     /*lista per i dati del primo file*/
	struct num *listb;     /*lista per i dati del secondo file*/
	struct num *orda;      /*lista per i dati del primo ordinati*/
	struct num *ordb;      /*lista per i dati del secondo ordinati*/
	struct num *tmp;
	struct num *temp;
	char nome[LEN];
	int numdati;
	FILE *fp;   /*Dichiaro il puntatore a file*/

	printf("Inserire il nome del file da aprire ");
	scanf("%s", nome);   /*Richiedo il nome del file da aprire*/
	lista=NULL;    /*Inizializzo la lista*/
	fp=fopen(nome, "r");   /*Apro il file in sola lettura*/
	if(fp==NULL)
	{
		printf("Errore il file non esiste\n");
		return 0;
	}
	printf("Lettura del file in corso ");
	while(!feof(fp))
	{
	     tmp=malloc(sizeof(struct num));   /*Inizializzo la struttura dati temporanea*/
	     tmp->next=NULL;
	     numdati=fscanf(fp, "%d\n", &tmp->numero); /*Acquisisco i dati da file*/
	     if (numdati!=1)break;  /*Se leggo troppidati mi fermo*/
	     if (lista==NULL) /*Se e' il primo dato */
		lista=tmp;  /*pongo la lista uguale ai dati temporanei*/
	     else     /*altrimenti passo alla funzione carica*/
		carica(lista, tmp);
	     printf(".");
	}
	printf("\n");
	fclose(fp);    /*chiudo il file*/
	printf("Inserire il nome del secondo file ");
	scanf("%s", nome);  /*Richiedo il nome del secondo file*/
	listb=NULL;  /*Inizializzo la lista*/
	fp=fopen(nome, "r");  /*Apro il file in sola lettura*/
	if(fp==NULL)
	{
		printf("Errore il file non esiste\n");
		return 0;
	}
	printf("Lettura del file in corso ");
	while(!feof(fp))
	{
	     tmp=malloc(sizeof(struct num));   /*Inizializzo la struttura dati temporanea*/
	     tmp->next=NULL;
	     numdati=fscanf(fp, "%d\n", &tmp->numero); /*Leggo i dati dal file*/
	     if (numdati!=1)break; /*Se ne leggo troppi mi fermo*/
	     if (listb==NULL)  /*Se e' il primo dato*/
		listb=tmp;  /*pongo la lista uguale al temporaneo*/
	     else
		carica(listb, tmp);  /*altrimenti passo alla funzione carica*/
	     printf(".");
	}
	printf("\n");
	fclose(fp);    /*chiudo il file*/
	salva_stampa(lista, listb); /*passo alla funzione per salvare e stampare*/
	orda=iniz();/*Inizializzo la prima lista ordinata*/
	printf("Ordinamento prima lista in corso ");
	for(tmp=lista;tmp!=NULL;tmp=tmp->next)  /*Eseguo un ciclo for per ordinare la lista*/
	{
	    temp=malloc(sizeof(struct num));
	    temp->numero=tmp->numero;    /*copio i dati della mia struttura in un'altra*/
	    temp->next=NULL;
	    ordina(temp, orda);  /*passo alla funzione di ordinamento*/
	    printf(".");
	}
	printf("\n");
	ordb=iniz(); /*Inizializzo la seconda lista ordinata*/
	printf("Ordinamento seconda lista in corso ");
	for(tmp=listb;tmp!=NULL;tmp=tmp->next) /*Eseguo un ciclo for per ordinare la lista*/
	{
	    temp=malloc(sizeof(struct num));
	    temp->numero=tmp->numero;  /*copio i dati della mia struttura in un'altra*/
	    temp->next=NULL;
	    ordina(temp, ordb);    /*passo alla funzione di ordinamento*/
	    printf(".");
	}
	printf("\n");
	salva_stampa(orda->next, ordb->next); /*passo alla funzione per stampare le liste ordinate*/
	return 0;
}

void carica(struct num *list, struct num *nuovo)
{
	struct num *p;

	for(p=list;p->next;p=p->next); /*scorro tutti i record filo all'ultimo*/
	p->next=nuovo;  /*aggiungo il nuovo record*/
}

void salva_stampa(struct num *a, struct num *b)
{
	struct num *p;
	struct num *g;
	FILE *fp; /*Dichiaro il puntatore a file*/
	char nome[LEN];

	printf("Inserire il nome su cui salvare la somma ");
	scanf("%s", nome);   /*Richiedo il nome del file da salvare*/
	fp=fopen(nome, "w"); /*Apro il file in lettura*/
	g=b;
	for(p=a;p!=NULL;p=p->next)   /*scorro la lista con un ciclo for*/
		if(g!=NULL)  /*Se la seconda lista non e' finita*/
		{
		    printf("NUMERI: %6d %6d TOTALI: %8d\n", p->numero, g->numero, (p->numero)+(g->numero)); /*Stampo a video*/
		    fprintf(fp,"%d\n", (p->numero)+(g->numero)); /*Stampo sul file*/
		    g=g->next;
		}
		else
		{
		    fclose(fp);  /* altrimenti chiudo il file ed esco dalla funzione*/
		    return;
		}
	fclose(fp);   /*Chiudo il file*/
}

struct num *iniz(void)
{
	struct num *p;

	/*Inizializzo le liste ordinate*/
	p=malloc(sizeof(struct num));
	p->next=NULL;
	p->numero=0;
	return p;
}

void ordina(struct num *g, struct num *lista)
{
	struct num *p;

	for(p=lista;p->next;p=p->next) /*Con un ciclo for scorro la lista ordinata*/
		if(p->next->numero > g->numero) /*Se il numero successivo della lista e' maggiore del mio numero*/
		{
		     g->next=p->next; /*Inserisco il nuovo record spostando i puntatori next*/
		     p->next=g;
		     return;
		}
	g->next=p->next;   /*Se finisco di scorre la lista lo aggiungo alla fine*/
	p->next=g;
}