#include #include #include #define TAILLE_CHAINE 100 #define MAX_PERSONNES 10 typedef struct { int j, m, a; } Date; typedef struct { char nom[TAILLE_CHAINE]; char prenom[TAILLE_CHAINE]; char telephone[TAILLE_CHAINE]; Date naissance; } Personne; typedef struct { Personne personnes[MAX_PERSONNES]; int nb; } Annuaire; Date lire_date(FILE* fp) { Date d; fscanf(fp, "%d", &d.j); fscanf(fp, "%d", &d.m); fscanf(fp, "%d", &d.a); return d; } void affiche_date(Date d) { printf("%2d/%2d/%4d\n", d.j, d.m, d.a); } int lire_personne(FILE* fp, Personne* p) { int res = fscanf(fp, "%s", p->nom); if (res == EOF) { return 1; } fscanf(fp, "%s", p->prenom); p->naissance = lire_date(fp); fscanf(fp, "%s", p->telephone); return 0; } void affiche_personne(Personne p) { printf("Prénom : %s\n", p.prenom); printf("Nom : %s\n", p.nom); printf("Téléphone : %s\n", p.telephone); printf("Naissance :"); affiche_date(p.naissance); } void construire_annuaire(FILE* fp, Annuaire* a) { int i, res; for (i = 0; i < MAX_PERSONNES; i++) { // res = lire_personne(&(*a)[i]); res = lire_personne(fp, &a->personnes[i]); if (res != 0) { a->nb = i; break; } } } void afficher_annuaire(Annuaire* a) { int i; for (i = 0; i < a->nb; i++) { affiche_personne(a->personnes[i]); } } char compare_dates(Date d1, Date d2) { if (d1.j == d2.j && d1.m == d2.m && d1.a == d2.a) { return 0; } else if (d1.a > d2.a || (d1.a == d2.a && (d1.m > d2.m || (d1.m == d2.m && d1.j > d2.j)))) { return 1; } else { return -1; } } char compare_nom(Personne p1, Personne p2) { int nomComp = strcmp(p1.nom, p2.nom); if (nomComp == 0) { return strcmp(p1.prenom, p2.prenom); } else { return nomComp; } } void triDate(Annuaire* annuaire) { int i, j, trie; Personne temp; for (i = annuaire->nb - 1; i >= 1; i--) { trie = 1; for (j = 0; j <= i - 1; j++) { if (compare_dates(annuaire->personnes[j+1].naissance, annuaire->personnes[j].naissance) < 0) { temp = annuaire->personnes[j+1]; annuaire->personnes[j+1] = annuaire->personnes[j]; annuaire->personnes[j] = temp; trie = 0; } } if (trie) { return; } } } void triNom(Annuaire* annuaire) { int i, j, trie; Personne temp; for (i = annuaire->nb - 1; i >= 1; i--) { trie = 1; for (j = 0; j <= i - 1; j++) { if (compare_nom(annuaire->personnes[j+1], annuaire->personnes[j]) < 0) { temp = annuaire->personnes[j+1]; annuaire->personnes[j+1] = annuaire->personnes[j]; annuaire->personnes[j] = temp; trie = 0; } } if (trie) { return; } } } int rech_dicho(Annuaire* annu, char nom[TAILLE_CHAINE]) { int a = -1, b = annu->nb; int m, cmp; while (b - a > 1) { m = (a + b) / 2; cmp = strcmp(nom, annu->personnes[m].nom); if (cmp == 0) { return m; } else if (cmp > 0) { a = m; } else { b = m; } } return -1; } void modifierTelephone(Personne* personne) { printf("Nouveau numéro de téléphone : "); scanf("%s", personne->telephone); } void sauvegarderPersonne(FILE* fp, Personne* p) { fprintf(fp, "%s\n", p->nom); fprintf(fp, "%s\n", p->prenom); fprintf(fp, "%d\n%d\n%d\n", p->naissance.j, p->naissance.m, p->naissance.a); fprintf(fp, "%s\n", p->telephone); } void sauvegarderAnnuaire(FILE* fp, Annuaire* a) { int i; for (i = 0; i < a->nb; i++) { sauvegarderPersonne(fp, &a->personnes[i]); } } int menu() { printf("→ Que faire ?\n"); printf("1) Afficher l'annuaire\n"); printf("2) Rechercher une personne\n"); printf("3) Modifier un numéro de téléphone\n"); printf("4) Sauvegarder et quitter\n"); printf("5) Quitter sans sauvegarder\n"); int reponse; scanf("%d", &reponse); while (reponse < 1 || reponse > 5) { printf("Choix invalide, veuillez réessayer.\n"); scanf("%d", &reponse); } return reponse; } int main(int argc, char* argv[]) { if (argc != 3) { printf("Usage : %s FICHIER_ENTREE FICHIER_SORTIE\n", argv[0]); return EXIT_FAILURE; } FILE* fp; fp = fopen(argv[1], "r"); if (fp == NULL) { printf("Impossible d'ouvrir le fichier %s.\n", argv[1]); return EXIT_FAILURE; } Annuaire a; construire_annuaire(fp, &a); fclose(fp); triNom(&a); int choix = 0, place; char nom[TAILLE_CHAINE]; while (choix < 4) { choix = menu(); switch (choix) { case 1: afficher_annuaire(&a); break; case 2: case 3: printf("Saisissez un nom à trouver dans l'annuaire : "); scanf("%s", nom); place = rech_dicho(&a, nom); if (place < 0) { printf("Inconnu."); break; } affiche_personne(a.personnes[place]); if (choix == 3) { modifierTelephone(&a.personnes[place]); } break; case 4: // On pouvait aussi ouvrir le fichier avant la boucle, mais cela garderait // un verrou sur le fichier assez longtemps. Ici, si l'utilisateur ne peut // pas écrire dans le fichier, il ne le saura qu'au dernier moment... fp = fopen(argv[2], "w"); if (fp == NULL) { printf("Impossible d'ouvrir le fichier %s.\n", argv[2]); return EXIT_FAILURE; } sauvegarderAnnuaire(fp, &a); fclose(fp); break; default: break; } } return EXIT_SUCCESS; }