/****************************************************************** Programme de gestion d'un repertoire telephonique http://www-sop.inria.fr/oasis/personnel/Carine.Courbis/c/ ********************************************************************/ #include #include #include #define MAX_NOM 20 #define MAX_PRENOM 20 #define MAX_REP 20 typedef struct{ char prenom[MAX_PRENOM]; char nom[MAX_NOM]; unsigned long tel; } Personne; typedef enum{FALSE, TRUE} Boolean; static Personne repertoire[MAX_REP]; static int nbPers = 0; /* Remplit le tableau tab de caracteres tapes au clavier jusqu'au caractere retour chariot exclu. Au maximum (taille-1) caracteres sont mis dans le tableau tab. Le caractere null est ajoute a la fin pour en faire une chaine. Parametres : tab un tableau de 'taille' elements qui sera rempli avec les caracteres saisis, taille le nombre d'elements max du tableau tab */ void saisieChaine(char tab[], int taille) { char car; int i = 0; /* on ignore tous les caracteres non alphanumeriques */ while( !isalpha(car=getchar())); do { /* on place le caractere dans le tableau */ tab[i++] = car; /* on continue jusqu'a fin du tableau ou caractere fin de ligne */ } while ( (i= MAX_REP) { printf("Impossible d'ajouter une nouvelle personne: le repertoire est plein"); return FALSE; } else { repertoire[nbPers++] = pers; return TRUE; } } /* Enlève la personne donnée du répertoire si elle est présente ; sinon affiche un message d'erreur pour avertir l'utilisateur. Parametres : nom, prenom (nom et prenom de la personne dela enlever) Retour : TRUE si la personne a pu être enlevée, FALSE sinon */ Boolean enlevePersonneDuRep(char * nom, char * prenom) { int indice = getIndicePersonne(nom, prenom); if (indice == -1) { /* si (nom, prenom) n'est pas dans le repertoire */ printf("%s %s n'est pas dans le repertoire !\n", prenom, nom); return FALSE; } else { /* sinon, on a trouve la personne a indice et il faut decaler les cases du Repertoire for(i = indice; i < nbPers - 1; i++ ) repertoire[i] = repertoire[i+1]; Cette solution est ok mais pas la meilleure car couteux de faire des decalages. Elle n'a de sens que si le repertoire est ordonne. Il est meilleur de mettre la derniere personne dans ce "trou". */ repertoire[indice] = repertoire[nbPers-1]; /* -1 car on va de 0 a nbPers-1 */ /* on a perdu une personne dans le Repertoire */ nbPers --; return TRUE; } } /* Saisie d'un numero de telephone (si le premier digit du numéro est zéro, il est enlevé) Retour : le numero de telephone donne ou 0 en cas de numero errone */ static unsigned long saisieNumeroDeTelephone() { int numeroOperateur; unsigned long numTel; printf("Numero de tel ? "); /* lit le 0 indiquant l'operateur preselectionne */ numeroOperateur = getchar(); if (numeroOperateur != '0') { if (('1' <= numeroOperateur) && (numeroOperateur <= '9')) /* on remet le caractere dans stdin */ ungetc(numeroOperateur, stdin); } scanf("%lu", &(numTel)); if ((numTel < 100000000) || (numTel > 999999999)) { printf("Le numero %lu parait errone.\n", numTel); numTel = 0; } return numTel; } /* Saisie du nom, prenom de la personne. Saisie aussi le numero de telephone de la personne (si le premier digit du numéro est zéro, il est enlevé) si doisSaisirNumTel est VRAI. Parametre : doisSaisirNumTel indique si le numero de telephone doit etre saisie aussi Retour : les infos d'une personne */ Personne saisiePersonne(Boolean doitSaisirNumTel) { Personne newPers; printf("Nom ? "); saisieChaine(newPers.nom, MAX_NOM); printf("Prenom ? "); saisieChaine(newPers.prenom, MAX_PRENOM); if (doitSaisirNumTel) newPers.tel = saisieNumeroDeTelephone(); else newPers.tel = 0; return newPers; } /* Retourne le numero de telephone (sur 9 chiffres normalement ie sans le digit indiquant l'operateur telephonique) de la personne donnee. Si la personne n'est pas dans le repertoire, retourne 0 Parametres : nom, prenom (nom et prenom de la personne recherchee) Retour : le numero de la personne recherchee si presente dans le repertoire, 0 sinon. */ unsigned long getNumero(char * nom, char * prenom) { int indice; if( (indice = getIndicePersonne(nom, prenom)) == -1) { printf("%s %s n'est pas dans le repertoire\n",prenom, nom); return 0; } return repertoire[indice].tel; } /* Si le (nom, prenom) est dans le repertoire, demande a l'utilisateur le nouveau numero de telephone. Retour : FALSE si la modification n'a pas pu se faire car (nom, prenom) pas dans le repertoire ou numero saisi errone. TRUE sinon. Parametres : nom, prenom (nom et prenom de la personne pour laquelle on souhaite changer le numero de telephone) */ Boolean changeNumero(char * nom, char * prenom) { int indicePers = getIndicePersonne(nom, prenom); if (indicePers == -1) { printf("%s %s n'est pas dans le repertoire",prenom, nom); return FALSE; } else { unsigned long numero = saisieNumeroDeTelephone(); if (numero != 0) { repertoire[indicePers].tel = numero; return TRUE; } else return FALSE; } } /* Affiche le contenu du repertoire ie la liste des personnes avec leur numero de telephone (ajoute le digit indiquant l'operateur telephonique France Telecom devant le numero de telephone). Si le repertoire est vide, indique que le repertoire est vide. */ void afficherRepertoire() { int i; /* si le repertoire est vide .... */ if(nbPers == 0) { printf("\n\tRepertoire vide !!\n"); return; } printf("\n\t-----------NOM-------------------PRENOM-------------TELEPHONE-----\n"); /* pour chaque Personne (chaque case du Repertoire) */ for( i = 0; i < nbPers; i++) { /* imprimer le nom */ printf("\t| %-20s\t",repertoire[i].nom); /* puis le prenom */ printf("| %-20s\t",repertoire[i].prenom); /* et enfin le tel avant de changer de ligne */ printf("| 0%lu |\n", repertoire[i].tel); } printf("\t------------------------------------------------------------------\n"); } /* Sauvegarde le repertoire telephonique dans un fichier de nom .repertoire Si ce fichier ne peut pas etre ouvert, indique un message d'erreur */ void sauvegardeRep() { FILE *fd; int i; if( (fd = fopen(".repertoire", "w")) == NULL) fprintf(stderr, "ATTENTION: le repertoire n'a pas pu etre sauvegarde !\n"); else { for(i = 0; i < nbPers ; i++ ) { // tabulation comme separation d'elements fprintf(fd, "%s\t",repertoire[i].nom); fprintf(fd, "%s\t",repertoire[i].prenom); fprintf(fd, "%lu\n", repertoire[i].tel); } fclose(fd); } } /* Recupere le repertoire sauve precedemment dans le fichier .repertoire Si ce fichier n'existe pas, le repertoire est initialise vide */ void recupereRep() { FILE *fd; printf("recupere Rep\n"); if( (fd = fopen(".repertoire", "r")) == NULL) fprintf(stderr, "ATTENTION: le repertoire n'a pas pu etre charge !\n"); else { while ((nbPers < MAX_REP) && (fscanf(fd, "%[^\t\n]\t%[^\n\t]\t%lu\n", &(repertoire[nbPers].nom), &(repertoire[nbPers].prenom), &(repertoire[nbPers].tel))==3)) nbPers ++; /* %[^\t\n] permet de pouvoir lire toute une chaine de caractere jusqu'a une tabulation ou un retour chariot (des espaces peuvent etre contenus dans la chaine). %s lit une chaine jusqu'a un espace, retour chariot ou tabulation (donc un espace est vu comme un separateur). Si on utilise %s, cela signifie que l'on ne pourra pas lire des noms/prenoms contenant plusieurs mots et donc des espaces. */ } } /* Affiche un menu permettant d'effectuer des operations sur le repertoire */ void afficherMenu() { printf("\t******************************************************************\n"); printf("\tChoisissez une option:\n"); printf("\t******************************************************************\n"); printf("\t\t s sort du programme\n"); printf("\t\t 1 affiche le repertoire courant\n"); printf("\t\t 2 recherche le numero de telephone \n"); printf("\t\t 3 ajoute une personne dans le repertoire\n"); printf("\t\t 4 ajoute une personne sans telephone \n"); printf("\t\t 5 enleve une personne du repertoire \n"); printf("\t\t 6 changer le numero de telephone \n"); printf("\t******************************************************************\n"); printf("\t Votre choix : "); } /* programme principal */ void main() { char car; Personne pers; unsigned long numTel; recupereRep(); do { afficherMenu(); /* ignore tous les caracteres non alphanumeriques */ while(!isalnum(car=getchar())); switch (car) { case 's': sauvegardeRep(); break; case '1': afficherRepertoire(); break; case '2': pers = saisiePersonne(FALSE); if((numTel = getNumero(pers.nom, pers.prenom))!=0) printf("Le numero de telephone de %s %s est: 0%lu\n", pers.prenom, pers.nom, numTel); else printf("%s %s n'a pas de numero enregistre\n",pers.prenom, pers.nom); break; case '3': setPersonneDansRep(saisiePersonne(1)); break; case '4': setPersonneDansRep(saisiePersonne(0)); break; case '5': pers = saisiePersonne(FALSE); if(enlevePersonneDuRep(pers.nom, pers.prenom)) printf("J'ai enleve %s %s du repertoire\n", pers.prenom, pers.nom); break; case '6': pers = saisiePersonne(FALSE); if(changeNumero(pers.nom, pers.prenom)) printf("J'ai change le telephone de %s %s\n", pers.prenom, pers.nom); break; default: fprintf(stderr,"%c: commande inconnue !\n",car); } } while (car != 's'); sauvegardeRep(); }