/* possibile soluzione all'esame del 24.11.2000*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
/* Lunghezza nome */
#define ML 100
/* nodo dell'albero binario di ricerca */
struct nodo{
char nome[ML];
unsigned int interno; /* su turbo C e' sufficiente */
unsigned int ufficio;
struct nodo *maggiori, *minori;
};
/* prototipi funzioni */
void *Malloc(size_t);
FILE *Fopen(const char *, const char *);
struct nodo *leggi_riga(FILE *);
struct nodo *inserisci_in_albero(struct nodo *, struct nodo *);
void stampa_ufficio(struct nodo *, int);
struct nodo *ricerca(struct nodo*, int);
/* evito l'utilizzo di variabili globali */
int main(int argc, char **argv){
/* un puntatore per dati temporanei e uno per
* la radice dell'albero */
struct nodo *tmp;
struct nodo *albero=NULL; /* il mio albero binario di ricerca */
/* file handler per lettura */
FILE *dati;
/* stringa e intero per lettura da tastiera */
char input[ML];
int cosafare;
/* PRIMA PARTE: leggo e interpreto il file */
dati=Fopen("interni.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 nell'albero binario */
albero=inserisci_in_albero(albero, tmp);
}
/* SECONDA PARTE: iterativamente chiedo un tasto
* ed eseguo l'operazione relativa */
while(1){
printf("Inserisci un comando: ");
/* leggo il comando */
fgets(input,ML,stdin);
/* lo converto in numero */
cosafare=atoi(input);
/* cerco di capire se e' composto da una cifra
* o piu` */
if(cosafare>10){
tmp=ricerca(albero, cosafare);
/* se tmp e' diverso da NULL allora lo stampo */
if (tmp) {
printf("%s - %d\n", tmp->nome, tmp->interno);
}
}
else
stampa_ufficio(albero,cosafare);
}
return EXIT_SUCCESS; /* codice di uscita senza errori */
}
/* questa funzione legge descrizione del bene e relativo prezzo 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));
letto->maggiori=letto->minori=NULL;
/* provo a leggere dal file i tre elementi che compongono la riga*/
nb=fscanf(a, "%d;%d;%[^\n]\n",&letto->ufficio,&letto->interno,letto->nome);
/* se e' riuscito a leggere una riga completa nb deve essere
* pari ad tre (numero dei componenti) */
if(nb!=3){
free(letto);
return NULL;
}
return letto;
}
/* questa funzione inserisce i dati in un albero binario e restituisce la
* radice, il codice ISBN e' usato come chiave */
struct nodo *inserisci_in_albero(struct nodo *tree, struct nodo *new){
/* se l'albero non esiste il primo nodo e'
* sicuramente la radice */
if(!tree)return new;
if(tree->interno<new->interno)
tree->maggiori=inserisci_in_albero(tree->maggiori, new);
}else
tree->minori=inserisci_in_albero(tree->minori, new);
}
return tree;
}
/* questa procedura ricerca nell'albero binario l`interno
* ne restituisce il puntatore oppure NULL */
struct nodo *ricerca(struct nodo *a, int c){
/* se il sottoalbero di ricerca non esiste ritorno
* NULL (non ho trovato l'interno) */
if(!a)return NULL;
/* a seconda del risultato ho trovato la chiave o
* devo continuare la ricerca */
if(a->interno==c) return a;
if(a->interno<c) return ricerca(a->maggiori, c);
return ricerca(a->minori, c);
}
/* E' un semplice attraversamento con verifica corrispondenza
* ufficio con quello da stampare */
void stampa_ufficio(struct nodo *a, int uff){
if(!a)return;
stampa_ufficio(a->maggiori, uff);
if(a->ufficio==uff) printf("%s - %d\n", a->nome, a->interno);
stampa_ufficio(a->minori, uff);
}
/* 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;
}