hcreate, hsearch et hdestroy de posix - Pourquoi réinventer la poudre?
Posix fournit trois fonctions hcreate(), hsearch et hdestroy() très faciles à utiliser, si vos besoins se limitent à créer un table et à rechercher des entrées dans cette table, ces fonctions devraient vous convenir . Les deux seuls inconvénients sont l'impossibilité de redimensionner la table après sa création, et l'impossibilité de supprimer une entrée.
Le programme d'exemple: hashposix.c
#include <stdio.h>
#include <stdlib.h>
#include <search.h>
#include <string.h>
#include <time.h>
#define LGLIGNE 1000 //lg max de chaque chaine de caracteres
int main() {
ENTRY e, *ep;
FILE *fp;
char fichier[100];
clock_t tick1,tick2;
char* str_ptr;
char mot[LGLIGNE],motcle[LGLIGNE];
unsigned int nbajout,ajout_table;
/////////////////////////////////////////////////////////
printf("\nChaques lignes doivent se terminer par un newline\nEntrez le nom du fichier:");
scanf("%100s",fichier);
ajout_table=0;
if ((fp=fopen(fichier,"r")) == NULL) {printf("\nErreur lecture fichier\n"); exit(-1);}
tick1=clock();
while (fgets(mot,LGLIGNE,fp) != NULL) {
if ((str_ptr=strchr(mot,'\n'))!=NULL) *str_ptr='\0'; //supprime le LF
if ((str_ptr=strchr(mot,'\r'))!=NULL) *str_ptr='\0'; //supprime le CR
ajout_table++;
}
tick2=clock();
fclose(fp);
printf("Nb de ligne:%u\n",ajout_table);
printf("nombre de ticks horloge:%7ld\n",tick2-tick1);
////////////////////////////////////////////////////////
printf("\nEntrez le nombre d'ajout (0:max):");
scanf("%u",&nbajout);
if (nbajout == 0) nbajout=ajout_table;
////////////////////////////////////////////////////////
hcreate(nbajout*1.5); //50% plus large pour limiter les collisions
ajout_table=0;
fp=fopen(fichier,"r");
tick1=clock();
while (fgets(mot,LGLIGNE,fp) != NULL) {
if ((str_ptr=strchr(mot,'\n'))!=NULL) *str_ptr='\0'; //supprime le LF
if ((str_ptr=strchr(mot,'\r'))!=NULL) *str_ptr='\0'; //supprime le CR
//prépare le mot clé
strcpy(motcle,"/");
strcat(motcle,mot);
strcat(motcle,"/");
//
e.key = motcle; //la cle
e.data = (void *)mot; //ici la donnée est simplement le mot en clé
ep = hsearch(e, ENTER); //ajoute la donnée
//
if (ep == NULL) { //si la table est pleine
fprintf(stderr, "Erreur - l'entrée aéchoué.\n");
exit(1);
}
ajout_table++;
if (ajout_table >= nbajout) {printf("\nNombre d'ajout atteint\n"); break;}
}
tick2=clock();
fclose(fp);
printf("Nombre de ticks horloge:%7ld\n",tick2-tick1);
*mot='\0';
while (strcmp(mot,"quit!") != 0) {
printf("Mot à chercher (quit!):");
scanf("%s",mot);
//prepare le mot à chercher
strcpy(motcle,"/");
strcat(motcle,mot);
strcat(motcle,"/");
//
e.key = motcle;
tick1=clock();
ep = hsearch(e, FIND); //trouve l'entrée
tick2=clock();
printf("Nombre de ticks horloge:%7ld\n",tick2-tick1);
printf("Résultat, Clé:%9.9s Donnée:%s\n",
ep ? ep->key : "NULL",
ep ? ep->data : "VIDE");
}
hdestroy(); //détruit la table et libére la mémoire
return 0;
}
//Exemple de la doc légérement adapté
//hcreate ne permet pas d'accroitre la dimension de la table et
//une seule table est permise
//hcreate_r, hsearch_r permettent plusieurs tables
//JP Redonnet - 16 janvier 2009