This repository has been archived on 2019-08-09. You can view files and clone it, but cannot push or open issues or pull requests.
s6-pa-tp/TP2/tp2.c
2017-02-16 21:54:45 +01:00

252 lines
6.1 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}