/*
	Risoluzione esercizio proposto nella esercitazione
	di martedi' 22/5/2001:

	"Costruire un programma che acquisisce da standard
	 input una sequenza di valori di tipo long int e
	 costruisce un file testuale contenente, uno per riga,
	 solo i valori della sequenza che sono strettamente
	 maggiori della media di tutti i valori. Il programma
	 domanda all'utente sia la lunghezza della sequenza
	 sia il nome del file da costruire."
*/

#include <stdio.h> /* per l'I/O */
#include <stdlib.h> /* per malloc(), free() */
#include <assert.h>

/* prototipi */
	int LeggiLunghezzaSequenza(void);
	void LeggiSequenza(long int *s, int n);
	double CalcolaMedia(long int *s, int n);
	char *LeggiNomeFile(char *msg);
	void ProduciOutput(char *nome, long int *s, int n, double media);

int LeggiLunghezzaSequenza(void) {
	int l;
	printf("Immetti la lunghezza della sequenza di long int: ");
	scanf("%d", &l);
	(void)getchar(); /* il cast serve solo per "azzittire"
						l'altrimenti inevitabile warning */
	return l;
}

void LeggiSequenza(long int *s, int n) {
	int i;
	for(i = 0; i < n; i++) {
		printf("#%d: ", i + 1);
		scanf("%ld", &s[i]);
	}
	(void)getchar(); /* il cast serve solo per "azzittire"
						l'altrimenti inevitabile warning */
	/* NB: ne e' sufficiente uno solo perche' gli altri invii
	   vengono "mangiati" automaticamente nella lettura degli interi */
	return;
}

double CalcolaMedia(long int *s, int n) {
	int i, somma = 0;
	for(i = 0; i < n; i++)
		somma += s[i]; /* cioe': somma = somma + s[i] */
	return (double)somma/n; /* cast necessario per non avere troncamenti */
}

/*
	La funz. che segue e' realizzata in maniera totalmente
	dinamica, con conseguenti lungaggini nel codice; tale presentazione
	ha un puro scopo dimostrativo dell'uso della realloc()
*/
char *LeggiNomeFile(char *msg) {
	char *nome, ch;
	int lun = 0;
	nome = malloc(sizeof(char));
	assert(nome != NULL);
	printf("%s", msg);
	ch = getchar();
	while(ch != '\n') {
		nome[lun] = ch;
		lun++;
		nome = realloc(nome, (lun + 1) * sizeof(char));
		assert(nome != NULL);
		ch = getchar();
	}
	/* NB: ci siamo "mangiati" l'invio finale! */
	nome[lun] = 0; /* terminazione della stringa */
	return nome;
}

void ProduciOutput(char *nome, long int *s, int n, double media) {
	FILE *f;
	int i;
	f = fopen(nome, "w");
	assert(f != NULL);
	for(i = 0; i < n; i++)
		if(s[i] > media)
			fprintf(f, "%ld\n", s[i]);
	fclose(f);
	return;
}

int main(void) {
	int	lunghseq, /* lunghezza sequenza */
		i;
	double media;
	long int *seq; /* per array dinamico per sequenza */
	char *nomefile; /* per array dinamico */

	lunghseq = LeggiLunghezzaSequenza();
	seq = malloc(lunghseq * sizeof(long int));
	assert(seq != NULL);
	LeggiSequenza(seq, lunghseq);
	media = CalcolaMedia(seq, lunghseq);
	nomefile = LeggiNomeFile("Inserisci nome file output: ");
	ProduciOutput(nomefile, seq, lunghseq, media);
	free(seq);
	return 0;
}

