#include <stdio.h> #include <stdlib.h> /* ANSI C vuole che tutte le struct abbiano nome */ typedef struct { char nome[31]; char cognome[31]; int g; int m; int a; int hasEmail; /* se TRUE allora c'e' l'email */ union { struct { char uname[51]; char domain[51]; } email; /* email */ struct { int pref_int; char prefisso[6]; int numero; } tel; /* telefono */ } et; /* email o telefono */ } Voce; /* prototipi delle funzioni */ int fine( char riga[]); int add( char riga[], Voce agenda[], int quanti); int del( char riga[], Voce agenda[], int quanti); int print( char riga[], Voce agenda[], int quanti); int prox( char riga[], Voce agenda[], int quanti); int sort_nome( char riga[], Voce agenda[], int quanti); int sort_cognome(char riga[], Voce agenda[], int quanti); int sort_compl( char riga[], Voce agenda[], int quanti); void print_voce(Voce * voce); #define NVOCI 20 #define MAXLINE 201 /* Programma principale */ int main(int argc, char* argv[]) { char riga[MAXLINE] = { 0 }; /* buffer per l'ultima riga letta */ Voce agenda[NVOCI] = { 0 }; /* vettore di NVOCI (20) voci */ int quanti = 0; /* numero di voci inserite */ /* leggo tutta una riga (al max MAXLINE caratteri) */ scanf("%200[^\n]",riga); /* continuo finche' non arriva il comando 'fine' */ while (!fine(riga)) { if (add(riga,agenda,quanti)) if (quanti<NVOCI) quanti---++; quanti -= del(riga,agenda,quanti); prox(riga,agenda,quanti); print(riga,agenda,quanti); sort_nome(riga,agenda,quanti); sort_cognome(riga,agenda,quanti); sort_compl(riga,agenda,quanti); scanf("\n%200[^\n]",riga); } return 0; } /* Riconosco il comando 'fine' torno TRUE se l'ho riconosciuto */ int fine( char riga[]) { return (0==strcmp(riga,"fine")); } /* Riconosco ed eseguo i comandi 'add <nome> <cognome> <data> tel <telefono>' 'add <nome> <cognome> <data> email <email>' torno TRUE se l'ho riconosciuto */ int add( char riga[], Voce agenda[], int quanti) { Voce nuova = { 0 }; char resto[MAXLINE] = { 0 }; /* prima riconosciamo nome e cognome e data di nascita */ if (6 != sscanf(riga,"add \"%30[^\"\n]\" \"%30[^\"\n]\" %2d-%2d-%4d %[^\n]", nuova.nome, nuova.cognome, &nuova.g, &nuova.m, &nuova.a, resto)) if (6 != sscanf(riga,"add \"%30[^\"\n]\" %30s %2d-%2d-%4d %[^\n]", nuova.nome, nuova.cognome, &nuova.g, &nuova.m, &nuova.a, resto)) if (6 != sscanf(riga,"add %30s \"%30[^\"\n]\" %2d-%2d-%4d %[^\n]", nuova.nome, nuova.cognome, &nuova.g, &nuova.m, &nuova.a, resto)) if (6 != sscanf(riga,"add %30s %30s %2d-%2d-%4d %[^\n]", nuova.nome, nuova.cognome, &nuova.g, &nuova.m, &nuova.a, resto)) return 0; /* TODO: gestire gli errori */ /* poi l'email o il telefono */ nuova.hasEmail = 0; if (2 == sscanf(resto,"email %[^@ \n]@%[^\n ]\n", nuova.et.email.uname, nuova.et.email.domain)) nuova.hasEmail = 1; else if (3 != sscanf(resto,"tel---+%3d-%5[0-9]-%10d\n", &nuova.et.tel.pref_int, nuova.et.tel.prefisso, &nuova.et.tel.numero)) { printf("email o numero errato\n"); return 0; } if (quanti==NVOCI) printf("piena\n"); else agenda[quanti] = nuova; /* trovato */ return 1; } /* Riconosco ed eseguo il comando 'del <nome> <cognome>' torno il numero di elementi cancellati */ int del( char riga[], Voce agenda[], int quanti) { char nome[31] = { 0 }; char cognome[31] = { 0 }; int cancellati = 0, i, j; /* prima riconosciamo nome e cognome e data di nascita */ if (2 != sscanf(riga,"del \"%30[^\"\n]\" \"%30[^\"\n]\"",nome, cognome)) if (2 != sscanf(riga,"del \"%30[^\"\n]\" %30s",nome, cognome)) if (2 != sscanf(riga,"del %30s \"%30[^\"\n]\"",nome, cognome)) if (2 != sscanf(riga,"del %30s %30s",nome, cognome)) return 0; /* TODO: gestire gli errori */ /* cerco tutte le voci che corrispondono */ for (i=0; i<quanti-cancellati; i---++) if (0==strcmp(agenda[i].nome, nome) && 0==strcmp(agenda[i].cognome,cognome)) { /* ogni voce trovata viene stampata */ print_voce(&agenda[i]); /* e le successive vengono spostate indietro di un posto */ for (j=i---+1; j<quanti; j++) agenda[j-1]=agenda[j]; cancellati---++; } if (0==cancellati) printf("nessuna\n"); return cancellati; } /* Riconosco ed eseguo la stampa di tutta la tabella (o di 'nessuna') torno TRUE se l'ho riconosciuto */ int print( char riga[], Voce agenda[], int quanti) { int i; if (0!=strcmp(riga,"print")) return 0; for (i=0; i<quanti; i---++) print_voce(&agenda[i]); if (0==quanti) printf("nessuna\n"); return 1; } /* stampa di una singola voce */ void print_voce(Voce * v) { /* costruisco il valore dell'ultima colonna dato che non so quanto e' lunga l'email mi tengo largo */ char lastcolumn[101] = { 0 }; if (v == NULL) return; /* tanto per evitare errori */ if (1 == v->hasEmail) sprintf(lastcolumn, "%s@%s", v->et.email.uname, v->et.email.domain ); else sprintf(lastcolumn, "---+%d-%0.5s-%d", v->et.tel.pref_int, v->et.tel.prefisso, v->et.tel.numero ); /* stampo la riga della tabella */ printf("|%30.30s|%30.30s|%02d-%02d-%04d|%-50.50s|\n", v->nome, v->cognome, v->g, v->m, v->a, lastcolumn); } /* Riconosco ed eseguo il comando 'prox <giorno> <mese>' */ int prox( char riga[], Voce agenda[], int quanti) { int g = 0; int m = 0; int i, j, trovato=0; /* prima riconosciamo la data di nascita */ if (2 != sscanf(riga,"prox %2d %2d", &g, &m)) return 0; /* TODO: gestire gli errori */ /* per fare i conti faccio partire il numero del giorno e del mese da 0 */ g--; m--; /* considero i mesi tutti lunghi 31 giorni */ for (i=0;i<12*31 && trovato==0;i---++) for (j=0; j<quanti; j---++) if ((agenda[j].g-1)---+(agenda[j].m-1)*31 == (g+m*31+i)%(12*31)) { trovato = 1; print_voce(&agenda[j]); } if (trovato==0) printf("nessuna\n"); return 1; } /* prototipo di qsort void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); */ /* confronto tra due voci per determinare quale nome viene prima */ int name_compare(const void * xx, const void * yy) { Voce * x = (Voce *) xx; Voce * y = (Voce *) yy; return strcmp(x->nome, y->nome); } /* confronto tra due voci per determinare quale cognome viene prima */ int surname_compare(const void * xx, const void * yy) { Voce * x = (Voce *) xx; Voce * y = (Voce *) yy; return strcmp(x->cognome, y->cognome); } /* confronto tra due voci per determinare quale compleanno viene prima */ int birthday_compare(const void * xx, const void * yy) { Voce * x = (Voce *) xx; Voce * y = (Voce *) yy; if (x->m < y->m) return -1; if (x->m > y->m) return---+1; if (x->g < y->g) return -1; if (x->g > y->g) return---+1; return 0; } /* Riconosco ed eseguo il comando 'sort nome' */ int sort_nome( char riga[], Voce agenda[], int quanti) { if (0!=strcmp(riga,"sort nome")) return 0; qsort(agenda, quanti, sizeof(Voce), name_compare); } /* Riconosco ed eseguo il comando 'sort cognome' */ int sort_cognome(char riga[], Voce agenda[], int quanti) { if (0!=strcmp(riga,"sort cognome")) return 0; qsort(agenda, quanti, sizeof(Voce), surname_compare); } /* Riconosco ed eseguo il comando 'sort compleanno' */ int sort_compl( char riga[], Voce agenda[], int quanti) { if (0!=strcmp(riga,"sort compleanno")) return 0; qsort(agenda, quanti, sizeof(Voce), birthday_compare); }
#include <stdio.h> #include <stdlib.h> #include <string.h> /* ANSI C vuole che tutte le struct abbiano nome */ typedef struct { char nome[31]; char cognome[31]; int g; int m; int a; int hasEmail; /* se TRUE allora c'e' l'email */ union { struct { char uname[51]; char domain[51]; } email; /* email */ struct { int pref_int; char prefisso[6]; double numero; } tel; /* telefono */ } et; /* email o telefono */ } Voce; /* prototipi delle funzioni */ int fine( char riga[]); int add( char riga[], Voce agenda[], int * quanti); int del( char riga[], Voce agenda[], int * quanti); int print( char riga[], Voce agenda[], int quanti); int prox( char riga[], Voce agenda[], int quanti); int sort_nome( char riga[], Voce agenda[], int quanti); int sort_cognome(char riga[], Voce agenda[], int quanti); int sort_compl( char riga[], Voce agenda[], int quanti); void print_voce(Voce * voce); #define NUMVOCI 20 #define MAXLINE 201 #define FALSE 0 #define TRUE 1 /* Programma principale */ int main(int argc, char* argv[]) { char riga[MAXLINE] = { 0 }; /* buffer per l'ultima riga letta */ Voce agenda[NUMVOCI] = { 0 }; /* vettore di NVOCI (20) voci */ int quanti = 0; /* numero di voci inserite */ int found = FALSE; /* leggo tutta una riga (al max MAXLINE caratteri) */ scanf("%200[^\n]",riga); /* continuo finche' non arriva il comando 'fine' */ while (!fine(riga)) { found = FALSE; found |= add(riga,agenda,&quanti); found |= del(riga,agenda,&quanti); found |= prox(riga,agenda,quanti); found |= print(riga,agenda,quanti); found |= sort_nome(riga,agenda,quanti); found |= sort_cognome(riga,agenda,quanti); found |= sort_compl(riga,agenda,quanti); /* if (!found) printf("comando non riconosciuto\n"); */ scanf("\n%200[^\n]",riga); } return FALSE; } /* Riconosco il comando 'fine' torno TRUE se l'ho riconosciuto */ int fine(char riga[]) { return (0==strcmp(riga,"fine")); } /* Riconosco ed eseguo i comandi 'add <nome> <cognome> <data> tel <telefono>' 'add <nome> <cognome> <data> email <email>' torno TRUE se l'ho riconosciuto */ int add(char riga[], Voce agenda[], int *quanti) { Voce nuova = { 0 }; /* nuova voce (variabile locale) */ char * dot = NULL; /* indice dell'ultimo carattere '.' nell'email */ /* uso due buffer di appoggio per contenere (a turno) la parte della linea non ancora esaminata */ char resto[MAXLINE] = { 0 }; /* resto della linea ancora non esaminata */ char resto1[MAXLINE] = { 0 }; /* resto della linea ancora non esaminata */ /* riconosciamo il comando (seguito da almeno uno spazio) */ if (1 != sscanf(riga,"add%*[ ]%[^\n]", resto)) return FALSE; /* riconosciamo il nome (seguito da almeno uno spazio) */ if (2 != sscanf(resto,"\"%30[^\"]\"%*[ ]%[^\n]", nuova.nome, resto1) && 2 != sscanf(resto,"%30[^ ]%*[ ]%[^\n]", nuova.nome, resto1)) { printf("nome errato\n"); return FALSE; } /* riconosciamo il cognome (seguito da almeno uno spazio) */ if (2 != sscanf(resto1,"\"%30[^\"]\"%*[ ]%[^\n]", nuova.cognome, resto) && 2 != sscanf(resto1,"%30[^ ]%*[ ]%[^\n]", nuova.cognome, resto)) { printf("cognome errato\n"); return FALSE; } /* riconosciamo la data (seguita da almeno uno spazio) */ if (4 != sscanf(resto,"%d-%d-%d%*[ ]%[^\n]", &nuova.g, &nuova.m, &nuova.a, resto1)) { printf("data errata\n"); return FALSE; } /* controlliamo il valore dei campi della data (tutti mesi da 31 giorni) */ if (nuova.g < 1 || nuova.g > 31 || nuova.m < 1 || nuova.m > 12 || nuova.a < 0 || nuova.a > 9999) { printf("data errata\n"); return FALSE; } /* poi vediamo se seguira' l'email o il telefono */ if (1 == sscanf(resto1,"email%*[ ]%[^\n]",resto)) { nuova.hasEmail = TRUE; /* leggiamo l'email (e non ci aspettiamo altri caratteri dopo) */ if (2 != sscanf(resto,"%46[^@ ]@%48[^@ ]%[^\n]", nuova.et.email.uname, nuova.et.email.domain, resto1)) { printf("email errata\n"); return FALSE; } /* controllo che non sia troppo lunga */ if (strlen(nuova.et.email.uname)---+strlen(nuova.et.email.domain)+1>50) { printf("email errata\n"); return FALSE; } /* controllo che il 'domain' contenga almeno un punto preceduto e seguito da qualcosa */ dot = rindex(nuova.et.email.domain,'.'); /* puntatore all'ultimo '.' */ if (dot == NULL || /* se non lo trovo */ dot == nuova.et.email.domain || /* o e' all'inizio */ 1 == strlen(dot)) { /* o e' alla fine */ printf("email errata\n"); return FALSE; } } else { if (1 == sscanf(resto1,"tel%*[ ]%[^\n]",resto)) { nuova.hasEmail = FALSE; /* leggiamo il telefono (e non ci aspettiamo altri caratteri dopo) */ if (3 != sscanf(resto,"---+%d-%5[0-9]-%d%[^\n]", &nuova.et.tel.pref_int, nuova.et.tel.prefisso, &nuova.et.tel.numero, resto1) || nuova.et.tel.pref_int>999 || nuova.et.tel.pref_int<=0 || nuova.et.tel.numero>9999999999.0 || nuova.et.tel.numero<=0) { printf("telefono errato\n"); return FALSE; } } else { printf("comando errato\n"); return FALSE; } } if (*quanti == NUMVOCI) printf("piena\n"); else agenda[(*quanti)---++] = nuova; /* trovato */ return TRUE; } /* Riconosco ed eseguo il comando 'del <nome> <cognome>' torno il numero di elementi cancellati */ int del(char riga[], Voce agenda[], int *quanti) { char nome[31] = { 0 }; char cognome[31] = { 0 }; int cancellati = 0, i, j; /* uso due buffer di appoggio per contenere (a turno) la parte della linea non ancora esaminata */ char resto[MAXLINE] = { 0 }; /* resto della linea ancora non esaminata */ char resto1[MAXLINE] = { 0 }; /* resto della linea ancora non esaminata */ /* riconosciamo il comando (seguito da almeno uno spazio) */ if (1 != sscanf(riga,"del%*[ ]%[^\n]", resto)) return FALSE; /* riconosciamo il nome (seguito da almeno uno spazio) */ if (2 != sscanf(resto,"\"%30[^\"]\"%*[ ]%[^\n]", nome, resto1) && 2 != sscanf(resto,"%30[^ ]%*[ ]%[^\n]", nome, resto1)) { printf("nome errato\n"); return FALSE; } /* riconosciamo il cognome (non seguito da altri caratteri) */ if (1 != sscanf(resto1,"\"%30[^\"]\"%[^\n]", cognome, resto) && 1 != sscanf(resto1,"%30[^ ]%[^\n]", cognome, resto)) { printf("cognome errato\n"); return FALSE; } /* cerco tutte le voci che corrispondono */ for (i=0; i<(*quanti)-cancellati; i---++) if (0==strcmp(agenda[i].nome, nome) && 0==strcmp(agenda[i].cognome,cognome)) { /* ogni voce trovata viene stampata */ /* print_voce(&agenda[i]); */ /* e le successive vengono spostate indietro di un posto */ for (j=i---+1; j<(*quanti); j++) agenda[j-1]=agenda[j]; cancellati---++; } if (0==cancellati) printf("nessuna\n"); (*quanti) -= cancellati; return TRUE; } /* Riconosco ed eseguo la stampa di tutta la tabella (o di 'nessuna') torno TRUE se l'ho riconosciuto */ int print(char riga[], Voce agenda[], int quanti) { int i; if (0!=strcmp(riga,"print")) return FALSE; for (i=0; i<quanti; i---++) print_voce(&agenda[i]); /* if (0==quanti) printf("nessuna\n"); */ return TRUE; } /* stampa di una singola voce */ void print_voce(Voce * v) { /* costruisco il valore dell'ultima colonna in un buffer dato che non so quanto e' lunga l'email mi tengo largo */ char lastcolumn[MAXLINE] = { 0 }; if (v == NULL) return; /* tanto per evitare errori */ if (1 == v->hasEmail) sprintf(lastcolumn, "%s@%s", v->et.email.uname, v->et.email.domain ); else sprintf(lastcolumn, "---+%d-%0.5s-%d", v->et.tel.pref_int, v->et.tel.prefisso, v->et.tel.numero ); /* stampo la riga della tabella */ printf("|%30.30s|%30.30s|%02d-%02d-%04d|%-50.50s|\n", v->nome, v->cognome, v->g, v->m, v->a, lastcolumn); } /* Riconosco ed eseguo il comando 'prox <giorno> <mese>' */ int prox( char riga[], Voce agenda[], int quanti) { int g = 0; int m = 0; int i, j, trovato=0; /* uso due buffer di appoggio per contenere (a turno) la parte della linea non ancora esaminata */ char resto[MAXLINE] = { 0 }; /* resto della linea ancora non esaminata */ char resto1[MAXLINE] = { 0 }; /* resto della linea ancora non esaminata */ /* riconosciamo il comando */ if (1 != sscanf(riga,"prox%*[ ]%[^\n]", resto)) return FALSE; /* riconosciamo la data di nascita */ if (2 != sscanf(resto,"%2d-%2d%[^\n]", &g, &m, resto1)) { printf("data errata\n"); return FALSE; } /* controlliamo i due valori (tutti mesi da 31 giorni) */ if (g < 1 || g > 31 || m < 1 || m > 12 ) { printf("data errata\n"); return FALSE; } /* per fare i conti faccio partire il numero del giorno e del mese da 0 */ g--; m--; /* considero i mesi tutti lunghi 31 giorni */ for (i=0;i<12*31 && trovato==0;i---++) for (j=0; j<quanti; j---++) if ((agenda[j].g-1)---+(agenda[j].m-1)*31 == (g+m*31+i)%(12*31)) { trovato = TRUE; print_voce(&agenda[j]); } if (trovato==0) printf("nessuna\n"); return TRUE; } /* prototipo di qsort void qsort( void *base, // inizio dell'array size_t nmemb, // numero di elementi size_t size, // dimensione di un elemento int(*compar)( // puntatore alla funzione che esegue il confronto const void *, // elemento da confrontare const void *)); // elemento da confrontare */ /* confronto tra due voci per determinare quale nome viene prima */ int name_compare(const void * xx, const void * yy) { Voce * x = (Voce *) xx; Voce * y = (Voce *) yy; return strcmp(x->nome, y->nome); } /* confronto tra due voci per determinare quale cognome viene prima */ int surname_compare(const void * xx, const void * yy) { Voce * x = (Voce *) xx; Voce * y = (Voce *) yy; return strcmp(x->cognome, y->cognome); } /* confronto tra due voci per determinare quale compleanno viene prima */ int birthday_compare(const void * xx, const void * yy) { Voce * x = (Voce *) xx; Voce * y = (Voce *) yy; if (x->m < y->m) return -1; if (x->m > y->m) return---+1; if (x->g < y->g) return -1; if (x->g > y->g) return---+1; return 0; } /* Riconosco ed eseguo il comando 'sort nome' */ int sort_nome( char riga[], Voce agenda[], int quanti) { if (0!=strcmp(riga,"sort nome")) return FALSE; qsort(agenda, quanti, sizeof(Voce), name_compare); return TRUE; } /* Riconosco ed eseguo il comando 'sort cognome' */ int sort_cognome(char riga[], Voce agenda[], int quanti) { if (0!=strcmp(riga,"sort cognome")) return FALSE; qsort(agenda, quanti, sizeof(Voce), surname_compare); return TRUE; } /* Riconosco ed eseguo il comando 'sort compleanno' */ int sort_compl( char riga[], Voce agenda[], int quanti) { if (0!=strcmp(riga,"sort compleanno")) return FALSE; qsort(agenda, quanti, sizeof(Voce), birthday_compare); return TRUE; } /******************************* fine *********************************/
![]() |
![]() |
Questo sito usa cookies, usandolo ne accettate la presenza. (CookiePolicy)
Torna al Dipartimento di Informatica ![]() |
|
![]() |
![]() |