#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STRL 20+1 // devo considerare anche termine stringa
struct anno{
unsigned int anno;
struct anno *min,*mag;
};
struct rivista{
char nome[STRL];
struct anno *anni; // puntatore al sottoalbero degli anni
struct rivista *min, *mag;
};
void die(char *error){
fprintf(stderr,error);
fprintf(stderr,"\n");
exit(EXIT_FAILURE);
}
// funzione che crea gli alberi degli anni
struct anno *inserisci_anno(struct anno *p, const unsigned int y){
if(!p){
struct anno *tmp;
tmp=malloc(sizeof(struct anno));
if(!tmp)
die("Errore in allocazione memoria");
tmp->mag=tmp->min=NULL;
tmp->anno=y;
return tmp;
}
if(p->anno>y)
p->min=inserisci_anno(p->min,y);
else
p->mag=inserisci_anno(p->mag,y);
return p;
}
// funzione che crea l'albero delle riviste
struct rivista *inserisci_rivista(struct rivista *p, struct rivista *n){
if(!p)
return n;
if(strcmp(p->nome, n->nome)>0)
p->min=inserisci_rivista(p->min,n);
else
p->mag=inserisci_rivista(p->mag,n);
return p;
}
// attraversamento inorder albero anni
void stampa_anni(struct anno *p){
if(!p)return;
stampa_anni(p->min);
printf("%d ",p->anno);
stampa_anni(p->mag);
}
// attraversamento inorder albero riviste
void stampa_riviste(struct rivista *p){
if(!p) return;
stampa_riviste(p->min);
printf("RIVISTA: %s\nANNI DI PUBBLICAZIONE: ",p->nome);
stampa_anni(p->anni);
printf("\n\n");
stampa_riviste(p->mag);
}
int main(int argc, char **argv){
FILE *riviste;
struct rivista *elencoriv=NULL, *nodotmp;
int n,y;
char c;
if(argc<2)
die("E' necessario fornire il file da aprire come argomento");
if(!(riviste=fopen(argv[1],"r")))
die("File non esistente");
// suppongo che il file inzii con '#', lo leggo per semplicita'
c=fgetc(riviste);
if(c!='#')
die("Errore di sintassi nel file");
while(1){ // ciclo lettura nomi riviste
nodotmp=malloc(sizeof(struct rivista)); // creo ed inizializzo
if(!nodotmp)
die("Errore di allocazione");
nodotmp->anni=NULL; // nodo temporaneo in cui carichero i dati
nodotmp->min=nodotmp->mag=NULL;
n=fscanf(riviste, "%[^\n]\n", nodotmp->nome);
if(feof(riviste)) // se non riesco a leggere
break; // vuol dire che sono arrivato in fondo al file
while(1){ // ciclo lettura anni
c=fgetc(riviste); // leggo primo carattere riga
if(c=='#'||feof(riviste)) // se leggo # vuol dire che ho gia' finito di leggere gli anni
break;
n=fscanf(riviste, "%d\n", &y); // leggo l'anno
nodotmp->anni=inserisci_anno(nodotmp->anni,y);
}
elencoriv=inserisci_rivista(elencoriv,nodotmp);
}
stampa_riviste(elencoriv);
}