#include #include #include #include typedef struct { void** tab; unsigned len; } ptrlist; typedef struct { long long int* tab; unsigned len; } intlist; typedef struct { char** tab; unsigned len; } strlist; /* LIBLIST.C*/ //prototypes des fonctions /**************************ptrlist**********************/ ptrlist ptrlist_create(unsigned len); void ptrlist_append(ptrlist* list, void* ptr); void ptrlist_remove(ptrlist* list, void* ptr); unsigned ptrlist_index(ptrlist* list, void* ptr); /**************************intlist**********************/ intlist intlist_create(unsigned len); void intlist_aff(intlist* list); void intlist_append(intlist* list,long long int nombre); void intlist_resize(intlist* list, unsigned newLen); void intlist_remove(intlist* list,unsigned index); unsigned intlist_count(intlist* list, long long int nb); _Bool intlist_inList(intlist* list, long long int nombre); int intlist_index(intlist* list, long long int nombre); void intlist_insert(intlist* list,long long int nombre, unsigned index); /**************************strlist**********************/ void strlist_destroy(strlist* list); strlist strlist_create(unsigned len); void strlist_aff(strlist* list); void strlist_append(strlist* list, char *chaine); void strlist_resize(strlist* list, unsigned newLen, _Bool freeElement); void strlist_remove(strlist* list,unsigned index, _Bool freeElement); unsigned strlist_count(strlist* list, char* chaine); _Bool strlist_inList(strlist* list, char* chaine); int strlist_index(strlist* list, char* chaine); void strlist_insert(strlist* list,char* chaine, unsigned index); /*LIBSTR.C*/ char* sub(char* string,unsigned debut,unsigned fin);//a liberer après char* replace(char*, char*, char*);//a liberer après void cleanStdin(void); char* addStr(char* str1, char* str2);//a liberer après long double strToNb(char *string); char* nbToStr(long double number);//a liberer après unsigned count(char* string, char* search); void pause(void); char* input(char *text);//a libérer après char* subReplace(char* string, unsigned debut, unsigned longueur, char* remplacement);//à liberer après /*ERRFONC.C*/ void freeAllPtr(void); //creation du tableau de pointeurs generiques a liberer en cas d’erreur ptrlist allocptr; #define ERROR_MALLOC "Erreur lors de l allocation des ressources (malloc)." #define ERROR_MEMSET "Erreur lors de l initialisation du pointeur (memset)." #define ERROR_REALLOC "Erreur lors de la reallocation de la memoire (realloc)." #define ERROR_PTR_NOT_IN_LIST "Erreur : Le pointeur n est pas dans la liste." #define ERROR_OUT_OF_RANGE "Erreur : Hors intervalle." #define ERROR_INT_NOT_IN_LIST "Erreur : Le nombre n est pas dans la liste." #define ERROR_STR_NOT_IN_LIST "Erreur : La chaine de caracteres nest pas dans la liste." #define ERROR_INPUT "Erreur lors de l entree utilisateur (scanf)." #define ERROR_STRCPY "Erreur lors de la copie de la chaine (strcpy)." #define ERROR_SSCANF "Erreur lors de la conversion en nombre (sscanf)." #define ERROR_SNPRINTF "Erreur lors de la conversion en chaine de caractere (snprintf)." void freeAllPtr(void) { printf("Longueur de allocptr a liberer : %u\n", allocptr.len); for (unsigned i = 0 ; i < allocptr.len ; i++) { free(allocptr.tab[i]); printf("libere element %u : %lu\n",i,allocptr.tab[i]); } free(allocptr.tab); return; } void quitError(char* message) { printf("%s\n",message); freeAllPtr(); exit(EXIT_FAILURE); } /*liste de fonctions transformées en err_fonc() :*/ void* err_malloc(size_t taille) { void* ptr=malloc(taille); if (ptr==NULL) { quitError(ERROR_MALLOC); } ptrlist_append(&allocptr, ptr); //printf("malloc %u\n",allocptr.len); return ptr; } void err_memset(void* ptr, int valeur, size_t taille) { void* err=memset(ptr, valeur, taille); if (err==NULL) { quitError(ERROR_MEMSET); } } void* err_realloc(void* ptr, size_t taille) { void* tmp=realloc(ptr, taille); if (tmp==NULL) { quitError(ERROR_REALLOC); } allocptr.tab[ptrlist_index(&allocptr, ptr)]=tmp; ptr=tmp; return ptr; } void err_free(void* ptr) { //printf("free %u\n",allocptr.len); free(ptr); ptrlist_remove(&allocptr,ptr); } void cleanStdin(void)// vide le buffer { int c = 0; while ((c = getchar()) != '\n' && c != EOF); } void pause(void)// { printf("\nAppuyez sur une touche pour continuer..."); cleanStdin(); //getchar(); } char* input(char *text)// { char* var=err_malloc(101*sizeof(char)); // allocation d'un pointeur pour l'entrée de l'utilisateur (+1 char pour le caractère nul) err_memset(var,(char)0,101*sizeof(char));//initialise le pointeur à '\0' partout //on effectue l'entrée printf("%s",text); int err = scanf("%100[^\n]",var); if (err!=1) { quitError(ERROR_INPUT); } cleanStdin(); //crée un deuxième pointeur pour y copier le contenu de l'entrée de la vraie longueur char* newVar = err_malloc(sizeof(char)*(strlen(var)+1));//réserve une place de la longueur de l'entrée + 1 pour le caractère nul err_memset(newVar,0,sizeof(char)*(strlen(var)+1));//initialise tout à 0 void * ptrtest=strcpy(newVar,var);//copie de var dans newVar if (ptrtest==NULL) { quitError(ERROR_STRCPY); } err_free(var);var=NULL;//libération de var return newVar; } unsigned count(char* string, char* search)//compte le nombre d'occurrences d'une chaîne dans une autre { unsigned count=0; if ( strlen(search) > strlen(string) )//si la chaîne à rechercher est plus grande que celle dans laquelle on effectue la recherche { quitError(ERROR_OUT_OF_RANGE); } char* tempstr; for(int i=0;i<=strlen(string)-strlen(search);i++) { tempstr=sub(string,i,i+strlen(search)-1);//on va tester la sous chaine de position i if ( strcmp(search,tempstr)==0 ) { count++; } err_free(tempstr); } return count; } char* sub(char* string,unsigned debut,unsigned fin)//permet d'extraire une sous-chaine { int longueur = fin-debut+1; if (debut+longueur > strlen(string) || longueur < 0) { quitError(ERROR_OUT_OF_RANGE); } char* newStr = err_malloc(longueur * sizeof(char)+1);//allocation d'un pointeur err_memset(newStr,0,longueur*sizeof(char)+1);//initialisation à 0 for (int i=0; i strlen(string)) { quitError(ERROR_OUT_OF_RANGE); } char* debutChaine=sub(string,0,debut-1);//prend le début char* suiteChaine=addStr(debutChaine,remplacement);//ajoute la chaîne de remplacement char* fin = sub(string,debut+longueur,strlen(string)-1); char* resultat=addStr(suiteChaine,fin);//ajoute la fin err_free(debutChaine);err_free(suiteChaine);err_free(fin); return resultat; } char* replace(char* string, char* aRemplacer, char* remplacement)//remplace toutes les occurrences d’une chaine par une autre { char* ptrSubStr=0; char* tmp; /*création d'une nouvelle chaine pour effectuer le remplacement*/ char* chnRemplacee=err_malloc(sizeof(char)*strlen(string)+1); strcpy(chnRemplacee,string); while ((ptrSubStr=strstr(chnRemplacee,aRemplacer)) != NULL)//appels successifs a subReplace tant que l’on detecte la chaine a remplacer dans string { tmp=subReplace(chnRemplacee,(int)ptrSubStr-(int)chnRemplacee,strlen(aRemplacer),remplacement);//enregistrement du résultat dans une chaine temporaire pour pouvoir libérer le contenu pointé par string avant de réaffecter string err_free(chnRemplacee); chnRemplacee=tmp; } return chnRemplacee; } //ptrlist ptrlist ptrlist_create(unsigned len)// crée une liste de pointeurs { ptrlist list;//crée la structure list.tab=err_malloc(len*sizeof(void*));//initialise le tableau de longueur len avec de zéros err_memset(list.tab,0,len); list.len=len;//initialise la bonne longueur return list;//retourne la structure } void ptrlist_append(ptrlist* list, void* ptr)//ajoute un élément à la fin de la liste { void **tmp = realloc(list->tab, (list->len+1)*sizeof(void*));//réallocation de list.tab if (tmp==NULL) { quitError(ERROR_REALLOC); } list->tab= tmp;//affectation du pointeur de tmp vers list.tab list->tab[list->len]=ptr;//affecte nombre au dernier élément list->len++;//incrémente la longueur } unsigned ptrlist_index(ptrlist* list, void* ptr) { for (unsigned i=0; ilen; i++) { if (ptr==list->tab[i]) { return i; } } quitError(ERROR_PTR_NOT_IN_LIST); } void ptrlist_remove(ptrlist* list, void* ptr)//supprime un élément de la liste { unsigned index = ptrlist_index(&allocptr, ptr); void **tmp; if (list->len==1) { free(list->tab); tmp= malloc(0); if (tmp==NULL) { quitError(ERROR_MALLOC); } } else { for (unsigned i = index ; i < list->len -1; i++)//décale tous les éléments à partir de celui à supprimer list->tab[i]=list->tab[i+1]; tmp = realloc(list->tab, (list->len-1)*sizeof(void*));//réalloue un nouveau pointeur de la bonne taille if (tmp==NULL) { quitError(ERROR_REALLOC); } } list->tab = tmp; list->len--;//décrémentation de la longueur } //intlist intlist intlist_create(unsigned len)// crée une liste d'entiers { intlist list;//crée la structure list.tab=err_malloc(len*sizeof(long long int));//initialise le tableau de longueur len avec de zéros err_memset(list.tab,0,len); list.len=len;//initialise la bonne longueur return list;//retourne la structure } void intlist_aff(intlist* list)//affiche une liste d'entiers { if (list->len == 0)//si la liste a une longueur de zéro { printf("[]\n"); } else { printf("["); for ( unsigned i = 0 ; i < list->len -1 ; i++)//affiche les éléments du premier à l'avant-dernier printf("%lli, ",list->tab[i]); printf("%lli]\n",list->tab[list->len-1]);//affiche le dernier élément } } void intlist_append(intlist* list,long long int nombre)//ajoute un élément à la fin de la liste { long long int *tmp = err_realloc(list->tab, (list->len+1)*sizeof(long long int));//réallocation de list.tab list->tab = tmp;//affectation du pointeur de tmp vers list.tab list->tab[list->len]=nombre;//affecte nombre au dernier élément list->len++;//incrémente la longueur } void intlist_resize(intlist* list, unsigned newLen)//redimensionne la liste avec la nouvelle longueur { long long int *tmp = err_realloc(list->tab, newLen*sizeof(long long int));//réalloue un pointeur de la nouvelle taille list->tab = tmp; if (newLen > list->len)//initialisation des nouveaux éléments à 0 si nouveaux éléments il y a { for (unsigned i = list->len ; i < newLen ; i++) list->tab[i]=0; } list->len=newLen;//modification de la longueur } void intlist_remove(intlist* list,unsigned index)//supprime un élément de la liste { if (index > list->len-1) { quitError(ERROR_OUT_OF_RANGE); } for (unsigned i = index ; i < list->len -1; i++)//décale tous les éléments à partir de celui à supprimer list->tab[i]=list->tab[i+1]; long long int *tmp = err_realloc(list->tab, (list->len-1)*sizeof(long long int));//réalloue un nouveau pointeur de la bonne taille list->tab = tmp; list->len--;//décrémentation de la longueur } unsigned intlist_count(intlist* list, long long int nb) { unsigned count=0; for (unsigned i = 0 ; i < list->len ; i++) { if (list->tab[i] == nb) { count++; } } return count; } _Bool intlist_inList(intlist* list, long long int nombre) { for (unsigned i=0; ilen; i++) { if (nombre==list->tab[i]) { return 1; } } return 0; } int intlist_index(intlist* list, long long int nombre) { for (unsigned i=0; ilen; i++) { if (nombre==list->tab[i]) { return i; } } quitError(ERROR_INT_NOT_IN_LIST); } void intlist_insert(intlist* list,long long int nombre, unsigned index)//ajoute un élément à la place indiquée { if (index > list->len) { quitError(ERROR_OUT_OF_RANGE); } long long int *tmp = err_realloc(list->tab, (list->len+1)*sizeof(long long int));//réallocation de list.tab list->tab = tmp;//affectation du pointeur de tmp vers list.tab for (unsigned i = list->len ; i > index; i--)//décale tous les éléments d’une case en + jusqu’a la place a inserer list->tab[i]=list->tab[i-1]; list->tab[index]=nombre; list->len++;//incrémente la longueur } //strlist strlist strlist_create(unsigned len) { strlist list; list.tab=err_malloc(len*sizeof(char*)); err_memset(list.tab,0,len); list.len=len; return list; } void strlist_aff(strlist* list) { if (list->len == 0) { printf("[]\n"); } else { printf("["); for ( int i = 0 ; i < list->len -1 ; i++) (list->tab[i]==NULL) ? printf("\"\", ") : printf("\"%s\", ",list->tab[i]);//affiche "" si le pointeur est nul (list->tab[list->len-1]==NULL) ? printf("\"\"]\n") : printf("\"%s\"]\n",list->tab[list->len-1]);//dernier élément } } void strlist_append(strlist* list, char *chaine) { char **tmp = err_realloc(list->tab, (list->len+1)*sizeof(char*)); if (tmp == NULL){exit(-1);} list->tab = tmp; list->tab[list->len]=chaine; list->len++; } void strlist_destroy(strlist* list) { for (unsigned i=0 ; i < list->len;i++) { err_free(list->tab[i]); } err_free(list->tab); } void strlist_resize(strlist* list, unsigned newLen, _Bool freeElement) { //il faut au préalable libérer les éléments qui vont être tronqués si la nouvelle longueur est plus petite if (newLen < list->len && freeElement) { for (unsigned i = newLen ; i < list->len ; i++) err_free(list->tab[i]); } char **tmp = err_realloc(list->tab, newLen*sizeof(char*)); list->tab = tmp; if (newLen > list->len)//on initialise les nouveaux elements si nouveaux elements il y a { for (unsigned i = list->len ; i < newLen ; i++) list->tab[i]=(char*)0; } list->len=newLen; } void strlist_remove(strlist* list,unsigned index, _Bool freeElement)//indiquer si il faut libérer l'élément avant de le supprimer { if (index > list->len-1) { quitError(ERROR_OUT_OF_RANGE); } char **tmp; if (list->len==1) { if (freeElement) { err_free(list->tab[0]); } err_free(list->tab); tmp = err_malloc(0); } else { if (freeElement) {err_free(list->tab[index]);} for (unsigned i = index ; i < list->len -1; i++) list->tab[i]=list->tab[i+1]; tmp = err_realloc(list->tab, (list->len-1)*sizeof(char*)); } list->tab = tmp; list->len--; } unsigned strlist_count(strlist* list, char* chaine) { unsigned count=0; for (unsigned i = 0 ; i < list->len ; i++) { if (strcmp(list->tab[i],chaine)==0) { count++; } } return count; } _Bool strlist_inList(strlist* list, char* chaine) { for (unsigned i=0; ilen; i++) { if (strcmp(list->tab[i],chaine)==0) { return 1; } } return 0; } int strlist_index(strlist* list, char* chaine) { for (unsigned i=0; ilen; i++) { if (strcmp(chaine,list->tab[i])==0) { return i; } } quitError(ERROR_STR_NOT_IN_LIST); } void strlist_insert(strlist* list,char* chaine, unsigned index)//ajoute un élément à la place indiquée { if (index > list->len) { quitError(ERROR_OUT_OF_RANGE); } char **tmp = err_realloc(list->tab, (list->len+1)*sizeof(char*));//réallocation de list.tab list->tab = tmp;//affectation du pointeur de tmp vers list.tab for (unsigned i = list->len ; i > index; i--)//décale tous les éléments à partir de celui à supprimer list->tab[i]=list->tab[i-1]; list->tab[index]=chaine; list->len++;//incrémente la longueur } //structure de votre fonction main() int main(void) { allocptr.tab=malloc(0);// crée la liste qui contiendra les pointeurs alloués dynamiquement allocptr.len=0; freeAllPtr();//permet de libérer tous les pointeurs alloués dynamiquement par err_malloc() en cas de fuite de mémoire return 0; }