/*
  Inserisce le medie in un file: ogni
volta che trova un elemento negativo,
mette subito dopo la media.
*/

#include<stdlib.h>
#include<stdio.h>


/* il tipo lista */

struct NodoLista {
  int val;
  struct NodoLista *next;
};

typedef struct NodoLista *TipoLista;


/*
  stampa di una lista di lunghezza generica
*/

void StampaLista(TipoLista l) {
  TipoLista s;

  s=l;
  while(s!=NULL) {
    printf("%d ", (*s).val);
    s=(*s).next;
  }

  printf("\n");
}


/*
  legge una lista, in ordine
*/

TipoLista LeggiListaFile(char *nomefile) {
  FILE *fd;
  int res;
  int x;
  TipoLista l, s;


	  		/* apre il file */
  fd=fopen(nomefile, "r");
  if(fd==NULL) {
    perror("Errore in apertura del file");
    exit(1);
  }


			/* legge gli elementi in ordine */
  l=NULL;

  while(1) {
    res=fscanf(fd, "%d", &x);
    if(res!=1)
      break;

    if(l==NULL) {
      l=malloc(sizeof(struct NodoLista));
      s=l;
    }
    else {
      s->next=malloc(sizeof(struct NodoLista));
      s=s->next;
    }

    s->val=x;
    s->next=NULL;
  }


			/* chiude il file */
  fclose(fd);

  return l;
}


/*
  aggiunta di un elemento in testa alla lista
*/

void InserisciTestaLista(TipoLista *pl, int e) {
  TipoLista t;

  t=malloc(sizeof(struct NodoLista));
  (*t).val=e;
  (*t).next=*pl;

  *pl=t;
}


/*
  inserisce le medie
*/

void InserisciMedie(TipoLista l) {
  TipoLista s, t;
  int somma, numero;

			/* se la lista e' vuota, va lasciata cosi' */
  if(l==NULL)
    return;

			/* inizializza somma parziale e numero elementi
			incontrati finora */
  somma=0;
  numero=0;


			/* scansione della lista */
  s=l;

  while(s!=NULL) {

			/* aggiorna somma e numero di elementi trovati */
    somma=somma+s->val;
    numero++;


			/* se l'elemento e' negativo, aggiunge la media
			fra questo e il successivo */
    if(s->val<0) {
      t=s->next;
      s->next=malloc(sizeof(struct NodoLista));

      s=s->next;

      s->val=somma/numero;
      s->next=t;
    }

			/* passa al successivo elemento */
    s=s->next;
  }
}


/*
  main
*/

int main(int argn, char *argv[]) {
  FILE *fd;
  int res;
  int x;

  TipoLista l;


		/* controllo argomenti */
  if(argn-1!=1) {
    printf("Richesto un solo argomento: ");
    printf("il nome del file che contiene la lista\n");
    exit(1);
  }


  		/* legge la lista da file */
  l=LeggiListaFile(argv[1]);


		/* stampa la lista */
  StampaLista(l);


		/* inserisce le medie */
  InserisciMedie(l);


                /* stampa la lista */
  StampaLista(l);

  return 0;
}
