Canalblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Publicité
LINUX & OPEN SOURCE
17 janvier 2009

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

Publicité
Publicité
Commentaires
LINUX & OPEN SOURCE
Publicité
Archives
Publicité