/* Svolgimento esercizio d'esame del 20/10/1998 */

#define M 9
#define N 12

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

struct elem {
	char parola[2]; /* attenzione: assenza terminatore!!
	                   non verranno usate funzioni per manipolare e/o stampare stringhe */
	struct elem *next;
};

typedef struct elem elementolista;

/* PROTOTIPI */
FILE *ApriFile(char *, char *);
void StampaLista(elementolista *);
elementolista *CreaElemento(char, char);
void InserisciInCoda(char, char, elementolista **, elementolista **);
elementolista *CostrusciListaParole(FILE *);
int VocalePresente(char *);
void EliminaElemento(elementolista **, elementolista *);
elementolista *EliminaVocali(elementolista *);
int main(void);
/* FINE PROTOTIPI */


FILE *ApriFile(char *nome, char *modo)
{
	FILE *f;
	f=fopen(nome,modo);
	if(f==NULL) {
		fprintf(stderr,"Errore apertura file %s in modalita` %s. Programma terminato.\n",nome,modo);
		exit(2);
	}
	return f;
}



void StampaLista(elementolista *e)
{
	int conta=0;
	
	while(e != NULL) {
		conta++;
		printf("Parola num. %d: %c%c\n", conta, e->parola[0], e->parola[1]);
		e=e->next;
	}
	return;
}



elementolista *CreaElemento(char ch1, char ch2)
{
	elementolista *nuovo;
	nuovo=malloc(sizeof(elementolista));
	if(nuovo==NULL) {
		fprintf(stderr,"Memoria esaurita. Programma terminato.\n");
		exit(3); 
	}
	nuovo->parola[0]=ch1;
	nuovo->parola[1]=ch2;
	nuovo->next=NULL;
	return nuovo;
}



void InserisciInCoda(char ch1, char ch2, elementolista **testa, elementolista **coda)
{
	elementolista *nuovo;
	
	nuovo=CreaElemento(ch1, ch2);
	if(*coda==NULL)
		*testa=nuovo;
	else
		(*coda)->next=nuovo;
	*coda=nuovo;
	return;
}



int VocalePresente(char *parola)
{
	int i;
	for(i=0; i<2; i++)
		/* sfrutta fortemente le caratteristiche della switch!! */
		switch (parola[i])
		{
			case 'a':
			case 'A':
			case 'e':
			case 'E':
			case 'i':
			case 'I':
			case 'o':
			case 'O':
			case 'u':
			case 'U': return 1;
		}
	return 0;
}



void EliminaElemento(elementolista **testa, elementolista *prec)
/* prec punta all'elemento che precede quello da eliminare; vale NULL se quest'ultimo e` il primo */
{
	elementolista *morituro;
	if(prec==NULL) { /* elimino il primo */
		morituro=*testa;
		*testa=(*testa)->next;
	} else {
		morituro=prec->next;
		prec->next=prec->next->next;
	}
	free(morituro);
	return;
}



elementolista *EliminaVocali(elementolista *testa)
{
	elementolista *e, *prec;
	
	e=testa;
	prec=NULL;
	while(e!=NULL) {
		if(VocalePresente(e->parola))
			EliminaElemento(&testa,prec); /* il prec non cambia in questo caso */
		else
			prec=e;
		e=prec->next;
	}
	return testa;
}



elementolista *CostrusciListaParole(FILE *f)
{
	elementolista *lista = NULL, *coda = NULL;
	char uno, due, tre;
	int lunghezza;
	
	uno='\0';
	due='\0';
	/* inizializzazioni a un valore sicuramente estraneo al cruciverba */
	
	while(!feof(f)) {
		lunghezza=0;
		tre=fgetc(f);
		if(tre==EOF)
			break; /* in realta` si esce qui dal ciclo!! */

		while((tre != '*')&&(tre != '\n')) { /* le parole terminano con '*' o con '\n' */
		                                     /* non c'e` bisogno di testare end-of-file */
			lunghezza++;
			uno=due;
			due=tre;
			tre=fgetc(f);
		}
		if(lunghezza==2)
			InserisciInCoda(uno,due,&lista,&coda);
	}	
	
	return lista;
}


int main(void)
{
	FILE *f;
	elementolista *listaparole2;
	
	f=ApriFile("CRUCI.TXT","r");
	listaparole2 = CostrusciListaParole(f);
	fclose(f);
	
	printf("Risultato funzione ""CostrusciListaParole"":\n");
	StampaLista(listaparole2);
	
	listaparole2 = EliminaVocali(listaparole2);

	printf("--\nRisultato funzione ""EliminaVocali"":\n");
	StampaLista(listaparole2);
	
	return 0;
}