/* possibile soluzione all'esame del 13.2.2001 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
/* costante per lunghezza stringhe */
#define ML 255
/* non e'richiesto ordinamento ma solo che si possano gestire
* un numero di elementi non predeterminato -> lista non ordinata */
struct nodo{
unsigned int primo;
unsigned int secondo;
struct nodo *prossimo;
};
/* prototipi funzioni */
void *Malloc(size_t);
FILE *Fopen(const char *, const char *);
struct nodo *leggi_riga(FILE *);
struct nodo *inserisci_in_lista(struct nodo *, struct nodo *);
unsigned int lunghezza_lista(struct nodo *);
void ordina_risultati(long *, int);
/* evito l'utilizzo di variabili globali */
int main(int argc, char **argv){
/* un puntatore per dati temporanei e uno per
* la testa della lista */
struct nodo *tmp;
struct nodo *testa=NULL; /* lista inizialmente vuota */
/* file handler per lettura */
FILE *dati;
/* stringa per gestire lettura da tastiera */
char input[ML];
char comando;
int nn,ii;
long *ris;
/* PRIMA PARTE: leggo e interpreto il file */
dati=Fopen("numeri.txt","r");
while(1){
/* leggo una singola riga
* se non riesco la funzione restituisce NULL
* e lo interpreto come fine file ed esco */
tmp=leggi_riga(dati);
if(!tmp)break;
/* inserisco i dati nella lista */
testa=inserisci_in_lista(testa, tmp);
}
/* SECONDA PARTE: iterativamente chiedo un tasto
* ed eseguo l'operazione relativa */
/* ora so quante coppie di numeri ho letto */
nn=lunghezza_lista(testa);
/* alloco opportuno array per i risultati*/
ris=Malloc(nn*sizeof(long));
printf("Inserisci un comando: ");
/* leggo il comando */
fgets(input,ML,stdin);
/* considero solo il primo carattere*/
comando=input[0];
/* guardo se e'un carattere o una cifra,
* isalpha e isdigit erano probabilmente soluzioni
* piu'eleganti */
switch(comando){
case 'A':
for(ii=0,tmp=testa;tmp;ii++,tmp=tmp->prossimo)
ris[ii]=tmp->primo-tmp->secondo;
break;
case 'B':
for(ii=0,tmp=testa;tmp;ii++,tmp=tmp->prossimo) {
ris[ii]=tmp->primo-tmp->secondo;
ris[ii]=ris[ii]*ris[ii];
}
break;
default:
fprintf(stderr, "Errore! comando non riconosciuto!\n");
exit(EXIT_FAILURE);
}
/* ordino i risultati */
ordina_risultati(ris, nn);
printf("Risultati:\n");
for(ii=0;ii<nn;++ii)
printf("%d\n",ris[ii]);
return EXIT_SUCCESS; /* codice di uscita senza errori */
}
/* questa funzione restituisce il numero di elementi nella lista */
unsigned int lunghezza_lista(struct nodo *a){
if(!a)return 0;
return 1+lunghezza_lista(a->prossimo);
}
/* questa funzione legge una riga del file e ritorna cio' che ha letto
* se non riesce a leggere ritorna NULL */
struct nodo *leggi_riga(FILE *a){
struct nodo *letto;
int nb;
/* alloco struttura per dati */
letto=Malloc(sizeof(struct nodo));
/* provo a leggere dal file i tre elementi che compongono la riga*/
nb=fscanf(a, "%u %u\n", &letto->primo, &letto->secondo);
/* se e' riuscito a leggere una riga completa nb deve essere
* pari ad tre (numero dei componenti) */
if(nb!=2){
free(letto);
return NULL;
}
letto->prossimo=NULL;
return letto;
}
/* questa funzione inserisce i dati in una lista non
* ordinata e restituisce la testa */
struct nodo *inserisci_in_lista(struct nodo *head, struct nodo *new){
/* se la lista non esiste il primo nodo e'
* sicuramente la testa */
if(!head)return new;
/* altrimenti ricorsivamente inserisco in una sottolista */
head->prossimo=inserisci_in_lista(head->prossimo, new);
return head;
}
/* funzione di confronto per long necessaria per
* qsort() */
int comparalong(const void *a, const void *b){
if(*((long *)a)==*((long *)b)) return 0;
if(*((long *)a)>*((long *)b)) return 1;
return -1;
}
/* ordina i risultati appoggiandosi su qsort() */
void ordina_risultati(long *elenco, int numelem){
qsort(elenco,numelem,sizeof(long),comparalong);
}
/* solite procedure utilizzate durante il corso */
/*************************************************************************/
void *Malloc(size_t size)
{
void *genericp;
if((genericp=malloc(size))==NULL)
{
perror("Malloc");
exit(1);
}
return genericp;
}
/*************************************************************************/
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;
}