Daniele Nicolodi writes: > printf("-------------------------------------\n"); > printf(" Alunno: %s %s\n", e->cognome, e->nome); > printf("Matricola: %s\n", e->matricola); > printf(" Corso: %s\n", e->corso); > printf(" Voto: %d\n", e->voto); Volendo, il C ANSI permette una cosa del tipo printf("-------------------------------------\n" " Alunno: %s %s\n" "Matricola: %s\n" " Corso: %s\n" " Voto: %d\n", e->cognome, e->nome, e->matricola, e->corso, e->voto); (notare l'assenza di virgole tra le costanti stringa - che vengono pertanto concatenate dal compilatore in fase di compilazione in un'unica costante stringa). Hai il vantaggio di una printf() sola contro 5. Hai lo svantaggio che e` piu` prono ad errori se son piu` di una manciata di parametri. +++ In esame_fill() vale giustamente la considerazione di Flavio. In aggiunta, io userei strdup() che c'e` apposta e fa la stessa cosa. Inoltre darei un'occhiata al fatto che i parametri passati siano validi... strlen(NULL) dovrebbe andare in core dump secco, idem strdup(NULL). Considerato poi che la struct si tiene delle copie delle stringhe che passi come parametro, sarebbe il caso di dichiararle const per far capire al programmatore che le stringhe passate non vengono modificate (e, 3 volte su 4, che la proprieta` delle stesse rimane del chiamante). Inoltre cosi` non si lamenta se passi come parametri delle costanti stringa. Del tipo void esame_fill(struct esame * e, const char * nome, cont char * cognome, const char * matricola, const char * corso , int voto) { if(e->nome) free(e->nome); if(e->cognome) free(e->cognome); if(e->matricola) free(e->matricola); if(e->corso) free(e->corso); e->nome = nome ? strdup(nome) : NULL; e->cognome = cognome ? strdup(cognome) : NULL; e->matricola = matricola ? strdup(matricola) : NULL; e->corso = corso ? strdup(corso) : NULL; e->voto = voto; } (se non ci metto i ``!= NULL'' e` per mia abitudine storica... cmq e` perfettamente equivalente, anche sulle piattaforme dove NULL non e` all'indirizzo 0: ci pensa il compilatore). +++ In prospettiva, cmq, quando la struttura diventa grande con tanti membri, conviene fare tante funzioni `getter' e `setter' quanti sono gli attributi, invece che un metodone per impostare tutti gli attributi, del tipo int esame_setNome(struct esame * e, const char * nome) { char * newNome = NULL; int result = 0; if(nome) { newNome = strdup(nome); if(newNome) { if(e->nome) free(e->nome); e->nome = newNome; } else { result = -1; } } else { result = -1; } return result; } const char * esame_getNome(struct esame * e) { return e->nome; } (setNome e` una sbrodolata di if() giusto per controllare i parametri in ingresso, si sa mai...) Avendo funzioni di questo genere diventa poi semplice realizzare funzioni che creano una nuova struct esame come copia di una esistente, o che assegnano ad una struct esame i valori a partire da un'altra struct esame. Inoltre, posto che usi solo queste per accedere ai valori della struct, se un domani la rappresentazione interna cambia puoi sempre rivedere queste funzioni e basta invece che andare a cambiar tutti i riferimenti nel codice. -- Per iscriversi (o disiscriversi), basta spedire un messaggio con SOGGETTO "subscribe" (o "unsubscribe") a mailto:linuxtrent-request@xxxxxxxxxxxxxxxxx