diff --git a/.gitignore b/.gitignore index 26cb36f..443ee53 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ levallois.jpg *.synctex.gz *.toc *.ent +*.test diff --git a/C12.1.c b/C12.1.c index c1b40af..fa906d3 100644 --- a/C12.1.c +++ b/C12.1.c @@ -20,16 +20,23 @@ void description(personne* p){ } -int scanfs(char** dest, int length){ +int scanfs(char* dest, int length){ - if(fgets(*dest, length, stdin)==NULL){ + if(fgets(dest, length-1, stdin)==NULL){ return 1;// Une erreur est survenue lors de la lecture (trop long ?) } // On doit supprimer le retour à la ligne qu'a capturé fgets. int i; - for(i=0;i=length){// On a Overflow + // On nettoie les caracteres ecrits en trop + while( (!strchr(dest,'\n')) && (!strchr(dest,EOF))) + if(!fgets(dest, length-1,stdin)) + break; + return 2; + } + dest[i] = '\0'; return 0; } @@ -41,13 +48,15 @@ void demander(personne* p){ char* num = malloc(NumLength*sizeof(char)); if(num==NULL){free(initiales);return;} printf("Création d'une nouvelle personne : \n"); - printf("Initiales : "); - while(scanfs(&initiales,IntLength)){}; + do{ + printf("Initiales : "); + } while(scanfs(initiales,IntLength)); printf("Âge : "); scanf("%d", &age); getchar(); - printf("Numéro de téléphone : "); - while(scanfs(&num, NumLength)){}; + do { + printf("Numéro de téléphone : "); + } while(scanfs(num, NumLength)); p->initiales = initiales; p->age = age; diff --git a/C12.2.c b/C12.2.c index ab9e29a..6b3038e 100644 --- a/C12.2.c +++ b/C12.2.c @@ -2,6 +2,8 @@ #include #include +#define NameLength 16 + /* 1 */ /* @@ -55,7 +57,9 @@ struct personnage{ struct personnage* frereSuivantMaman; struct personnage* premierEnfant; struct personnage* chaineGlobale; - + + char shouldFreeNom; + }; /* 6 */ @@ -71,23 +75,27 @@ struct personnage* getByName(struct personnage* origin, char* name){ /* 7 */ -struct personnage* newUnrelated(struct personnage* origin, char* name){ - +struct personnage* newUnrelatedM(struct personnage** originp, char* name, char shouldFreeNom){ + if(name==NULL)return NULL; struct personnage* dest = (struct personnage*) malloc(sizeof(struct personnage)); dest->nom = name; + dest->shouldFreeNom = shouldFreeNom; dest->frereSuivantPapa = dest->frereSuivantMaman = dest; dest->pere = dest->mere = dest->premierEnfant = NULL; - if(origin!=NULL){ - while(origin->chaineGlobale!=NULL)origin = origin->chaineGlobale; - origin->chaineGlobale = dest; - } - dest->chaineGlobale = NULL; + + dest->chaineGlobale = *originp; + *originp = dest; + return dest; } +struct personnage* newUnrelated(struct personnage** originp, char* name){ + return newUnrelatedM(originp, name, 0); +} + /* 8 */ -void papounet(struct personnage* pere, struct personnage* enfant){ - +int papounet(struct personnage* pere, struct personnage* enfant){ + if(pere==NULL || enfant==NULL)return 1; enfant->pere = pere; if(pere->premierEnfant==NULL){ pere->premierEnfant = enfant; @@ -98,11 +106,12 @@ void papounet(struct personnage* pere, struct personnage* enfant){ fraterie->frereSuivantPapa = enfant; } enfant->frereSuivantPapa = pere->premierEnfant; + return 0; } /* 9 */ -void mamounette(struct personnage* mere, struct personnage* enfant){ - +int mamounette(struct personnage* mere, struct personnage* enfant){ + if(mere==NULL || enfant==NULL)return 1; enfant->mere = mere; if(mere->premierEnfant==NULL){ mere->premierEnfant = enfant; @@ -113,6 +122,7 @@ void mamounette(struct personnage* mere, struct personnage* enfant){ fraterie->frereSuivantMaman = enfant; } enfant->frereSuivantMaman = mere->premierEnfant; + return 0; } /* 10 */ @@ -139,22 +149,40 @@ void dumpState(struct personnage* liste){ } /* 11 */ -struct personnage* addRegistryEntry(struct personnage* liste, char* enfantN, char* pereN, char* mereN){ - +int scanfs(char* dest, int length){ + + if(fgets(dest, length-1, stdin)==NULL){ + return 1;// Une erreur est survenue lors de la lecture (trop long ?) + } + + // On doit supprimer le retour à la ligne qu'a capturé fgets. + int i; + for(i=0;i=length){// On a Overflow + // On nettoie les caracteres ecrits en trop + while( (!strchr(dest,'\n')) && (!strchr(dest,EOF))) + if(!fgets(dest, length-1,stdin)) + break; + return 2; + } + dest[i] = '\0'; + return 0; +} + +struct personnage* addRegistryEntryM(struct personnage** liste, char* enfantN, char* pereN, char* mereN, char shouldFreeNoms){ + if(enfantN==NULL) return NULL; struct personnage *enfant, *pere, *mere; - if(liste==NULL) - liste = newUnrelated(NULL, enfantN); - enfant = getByName(liste, enfantN); - if(enfant==NULL)enfant = newUnrelated(liste, enfantN); + enfant = getByName(*liste, enfantN); + if(enfant==NULL)enfant = newUnrelatedM(liste, enfantN, shouldFreeNoms&0b100); if(pereN!=NULL){ - pere = getByName(liste, pereN); - if(pere==NULL)pere = newUnrelated(liste, pereN); + pere = getByName(*liste, pereN); + if(pere==NULL)pere = newUnrelatedM(liste, pereN, shouldFreeNoms&0b010); papounet(pere, enfant); } if(mereN!=NULL){ - mere = getByName(liste, mereN); - if(mere==NULL)mere = newUnrelated(liste, mereN); + mere = getByName(*liste, mereN); + if(mere==NULL)mere = newUnrelatedM(liste, mereN, shouldFreeNoms&0b001); mamounette(mere, enfant); } @@ -162,13 +190,43 @@ struct personnage* addRegistryEntry(struct personnage* liste, char* enfantN, cha } +struct personnage* addRegistryEntry(struct personnage** liste, char* enfantN, char* pereN, char* mereN){ + return addRegistryEntryM(liste, enfantN, pereN, mereN, 0); +} + +struct personnage* askRegistryEntry(struct personnage** liste){ + char* enfantN = malloc(NameLength*sizeof(char)); + if(enfantN==NULL)return NULL; + char* pereN = malloc(NameLength*sizeof(char)); + if(pereN==NULL){free(enfantN);return NULL;} + char* mereN = malloc(NameLength*sizeof(char)); + if(mereN==NULL){free(pereN),free(enfantN);return NULL;} + + do{ + printf("Nom de l'enfant : "); + } while(scanfs(enfantN,NameLength)); + do{ + printf("Nom du père (vide pour non renseigné) : "); + } while(scanfs(pereN,NameLength)); + do{ + printf("Nom de la mère (vide pour non renseigné) : "); + } while(scanfs(mereN,NameLength)); + + // La chaine vide est représentée par un pointeur vers '\0' (la fin de la chaine) + if(*pereN=='\0'){free(pereN);pereN = NULL;} + if(*mereN=='\0'){free(mereN);mereN = NULL;} + + return addRegistryEntryM(liste,enfantN, pereN, mereN, 0b111); +} + + /* 12 */ // Voir le main à la fin du code. /* 13 */ void paspapa(struct personnage* batard){ - + if(batard==NULL)return;// On n'enleve aucun lien if(batard->frereSuivantPapa != batard){ if(batard->pere->premierEnfant == batard)batard->pere->premierEnfant = batard->frereSuivantPapa; struct personnage* fraterie = batard; @@ -186,7 +244,7 @@ void paspapa(struct personnage* batard){ /* 14 */ void pasmaman(struct personnage* batard){ - + if(batard==NULL)return; if(batard->frereSuivantMaman != batard){ if(batard->mere->premierEnfant == batard)batard->mere->premierEnfant = batard->frereSuivantMaman; struct personnage* fraterie = batard; @@ -250,7 +308,15 @@ struct personnage* orderPersos(struct personnage* liste){ /* 16 */ + +// L'objectif était de faire une sortie illisible, surtout lorsqu'il y a beaucoup de générations. +// Mais je peux mettre des parentheses +#define ParenthesesVraiNom 1 void printVraiNom(struct personnage* perso){ + if(perso==NULL){ + printf("personne");return; + } + if(ParenthesesVraiNom)printf("("); printf("%s", perso->nom); if(perso->mere !=NULL){ printf(", enfant de "); @@ -263,9 +329,11 @@ void printVraiNom(struct personnage* perso){ printf(", enfant de "); printVraiNom(perso->pere); } + if(ParenthesesVraiNom)printf(")"); } int printNthGP(struct personnage* racine, int hauteur, int dejafait){ + if(racine==NULL)return 0; if(hauteur==0){ printf(dejafait?", %s":"%s", racine->nom); return dejafait+1; @@ -283,6 +351,7 @@ int printNthGP(struct personnage* racine, int hauteur, int dejafait){ void dumpAncetres(struct personnage* racine){ + if(racine==NULL)return; printf("Ancêtres de %s\n", racine->nom); printf("Parents connus: "); @@ -306,7 +375,7 @@ void dumpAncetres(struct personnage* racine){ /* 17 */ int dumpNthDescendents(struct personnage* vieux, int gen){ - + if(vieux==NULL)return 0; int count = 0; if(vieux->premierEnfant == NULL)return 0; int sexe = vieux->premierEnfant->pere != vieux;// 1 si femme @@ -331,6 +400,8 @@ int dumpNthDescendents(struct personnage* vieux, int gen){ /* 18 */ void dumpDescendenceUntil(struct personnage* vieux, int maxh){ + if(vieux==NULL)return; + printf("Déscendence de %s\n", vieux->nom); printf("Enfants connus: "); @@ -355,7 +426,7 @@ void dumpDescendenceUntil(struct personnage* vieux, int maxh){ /* 19 */ int estSMoinsGeneration(struct personnage* moi, struct personnage* autre, int limit){ - + if(moi==NULL || autre==NULL)return 0; if(limit==0)return 1;// On a fait trop de tours de récursivité ! Forcément une problème. if(moi->premierEnfant == NULL)return 0; int sexe = moi->premierEnfant->pere != moi;// 1 si femme @@ -402,6 +473,7 @@ void freeListe(struct personnage* origin){ struct personnage* ori2 = origin; while(ori2!=NULL){ origin = ori2->chaineGlobale; + if(ori2->shouldFreeNom)free(ori2->nom); free(ori2); ori2 = origin; } @@ -413,21 +485,21 @@ void freeListe(struct personnage* origin){ int main(){ - struct personnage* liste; + struct personnage* liste = NULL; - liste = - addRegistryEntry(NULL ,"Brandon","Jihair","Saoul-Helene"); - addRegistryEntry(liste,"Jessica","Jihair","Saoul-Helene"); - //addRegistryEntry(liste,"Jessica","Jihair","Pamella"); // Jessica est déjà enregistrée pourtant ... - addRegistryEntry(liste,"Jonatan","Huggy","Pamella"); - addRegistryEntry(liste,"Brenda","Huggy","Saoul-Helene"); - addRegistryEntry(liste,"Jennifer","Jihair","Pamella"); - addRegistryEntry(liste,"Kevin","Huggy", NULL); - addRegistryEntry(liste,"Jacques",NULL, NULL); - addRegistryEntry(liste,"Valery","Jonathan","Jennifer"); - addRegistryEntry(liste,"Georges","Jonathan","Jennifer"); - addRegistryEntry(liste,"François","Jonathan","Jessica"); - addRegistryEntry(liste,"Charles","Kevin","Jessica"); + + addRegistryEntry(&liste ,"Brandon","Jihair","Saoul-Helene"); + addRegistryEntry(&liste,"Jessica","Jihair","Saoul-Helene"); + addRegistryEntry(&liste,"Jennifer","Jihair","Saoul-Helene"); + addRegistryEntry(&liste,"Jonatan","Huggy","Pamella"); + addRegistryEntry(&liste,"Brenda","Huggy","Pamella"); + addRegistryEntry(&liste,"Kevin","Huggy", "Pamella"); + addRegistryEntry(&liste,"Jacques",NULL, NULL); + addRegistryEntry(&liste,"Valery","Jonathan","Jennifer"); + addRegistryEntry(&liste,"Georges","Jonathan","Jennifer"); + addRegistryEntry(&liste,"François","Jonathan","Jessica"); + addRegistryEntry(&liste,"Charles","Kevin","Jessica"); + askRegistryEntry(&liste); // Entrée rendant la structure incohérente. //addRegistryEntry(liste,"Kevin","Charles","Jessica"); @@ -442,7 +514,7 @@ int main(){ printVraiNom(liste->chaineGlobale->chaineGlobale); printf("\n"); dumpAncetres(liste->chaineGlobale->chaineGlobale); - dumpDescendence(getByName(liste, "Jihair")); + dumpDescendenceUntil(getByName(liste, "Jihair"),3); printf("\n"); dumpState(liste);