Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1260 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Liste chainée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Liste chainée

n°1393199
mayapour
Posté le 22-06-2006 à 22:34:37  profilanswer
 

Bonjour,
 
J'ai besoin de conseils pour les listes chainées.
Mon programme fait ce que je veux, c'est à dire sauvegarde dans un fichier du login, pass et shell entré (option a) et liste (option l) ou efface (option d) (avec cryptage du mot de passe).
 
Mais voilà, je souhaiterai qu'il ne sauvegarde pas dans un fichier mais dans une liste chainée (donc en mémoire dynamique).
 
J'ai tenté de remplacer la structure ci dessous par quelque chose comme :
typedef struct Element{
               int val;
               struct Element *next;
}Element;  
Mais j'ai trop d'erreurs.
 
Des idées ?
 

Code :
  1. struct my_passwd
  2. {
  3.        char          pw_name[255];   /* user name */
  4.        char          pw_passwd[255]; /* password */
  5.        char          pw_shell[64];   /* default shell */
  6. } ;
  7. int woptions(int ac,char ***av)
  8. {
  9. int option2return;
  10. option2return=getopt(ac, *av,"adl" );
  11. if(getopt(ac,*av,"adl" ) != -1)
  12.        {
  13.               printf("my_passwd: usage -[adl] [file]\n" );
  14.        exit(EXIT_FAILURE);
  15.         }
  16. else
  17.  return option2return;
  18. }
  19. int ajoututilisateur(char *fichier)
  20. {
  21.        struct my_passwd      pwd;
  22. int                   fd;
  23. MD5_CTX ctx;
  24. memset(&pwd, 0,sizeof(pwd));
  25. printf("Username: " );
  26. scanf("%s",pwd.pw_name);
  27. printf("Password: " );
  28. scanf("%s",pwd.pw_passwd);
  29. MD5Init(&ctx);
  30. MD5Update(&ctx,pwd.pw_passwd,strlen(pwd.pw_passwd));
  31. MD5End(&ctx,pwd.pw_passwd);
  32. printf("Shell: " );
  33.     scanf("%s",pwd.pw_shell);
  34. if((fd = open(fichier, O_RDWR|O_APPEND)) == -1)
  35. {
  36.  perror("my_passwd" );
  37.  exit(EXIT_FAILURE);
  38. }
  39.    if((write(fd, &pwd, sizeof(pwd))) == -1)
  40. {
  41.   perror("my_passwd" );
  42.   exit(EXIT_FAILURE);
  43. }
  44. close(fd);
  45. return 1;  
  46. }
  47. int effaceutilisateur(char *fichier)
  48. {
  49.  struct my_passwd      pwd;
  50.      int                    fd;
  51.  int   userexist=0;
  52.  char   *nom;
  53.  int   taille;
  54.  int   totalsize=0;
  55.  nom=malloc(sizeof(char *));
  56.  memset(&pwd, 0,sizeof(pwd));
  57.  printf("Username: " );
  58.  scanf("%s",nom);
  59.  if((fd = open(fichier, O_RDWR)) == -1)
  60.          {
  61.                 perror("my_passwd" );
  62.                 exit(EXIT_FAILURE);
  63.          }
  64. while((taille=read(fd,&pwd,sizeof(pwd))) != 0)
  65. {
  66.  totalsize += taille;
  67.  if(strcmp(nom,pwd.pw_name) == 0)
  68.  {
  69.   while((taille=read(fd,&pwd,sizeof(pwd))) != 0)
  70.   {
  71.    lseek(fd,(totalsize-sizeof(pwd)),SEEK_SET);
  72.    if((write(fd, &pwd, sizeof(pwd))) == -1)
  73.           {
  74.            perror("my_passwd" );
  75.            exit(EXIT_FAILURE);
  76.            }
  77.    totalsize += taille;
  78.    lseek(fd,totalsize,SEEK_SET);
  79.   }
  80.   userexist=1;
  81.  }
  82. }
  83. close(fd);
  84. if(userexist==0)
  85. {
  86.  printf("my_passwd: unknown user %s\n",nom);
  87. }
  88. else
  89.  truncate(fichier,totalsize-sizeof(pwd));
  90. return 1;
  91. }
  92. int listeutilisateur(char *fichier)
  93. {
  94. struct my_passwd      pwd;
  95. int                   fd;
  96. char                   *nom;
  97. memset(&pwd, 0,sizeof(pwd));
  98.         if((fd = open(fichier, O_RDWR)) == -1)
  99.         {
  100.                       perror("my_passwd" );
  101.                       exit(EXIT_FAILURE);
  102.         }
  103.         while((read(fd,&pwd,sizeof(pwd))) != 0)
  104.         {
  105.           printf("Username: %s\n",pwd.pw_name);
  106.       printf("Password: %s\n",pwd.pw_passwd);
  107.       printf("Shell: %s\n\n",pwd.pw_shell);
  108.         }
  109.         close(fd);
  110.  return 1;
  111. }
  112. int nbrconf(int ac)
  113. {
  114. if(ac!=3)
  115. {
  116.  printf("my_passwd: usage -[adl] [file]\n" );
  117.  exit(EXIT_FAILURE);
  118. }
  119. else
  120.   return 1;
  121. }
  122. int fichierlu(char *fichier)
  123. {
  124. struct stat s_sb;
  125. if(lstat(fichier,&s_sb) != 0)
  126. {
  127.  perror("my_passwd" );
  128.  exit(EXIT_FAILURE);
  129. }
  130. else
  131. {
  132.  if(!S_ISREG(s_sb.st_mode))
  133.  {
  134.   printf("my_passwd: need a file\n" );
  135.   printf("my_passwd: usage -[adl] [file]\n" );
  136.  }
  137.  else
  138.   return 1;
  139. }
  140. }
  141. void priseoption(int choixoption, char *fichier)
  142. {
  143.   switch (choixoption)
  144.          {
  145.              case 'a':
  146.                 ajoututilisateur(fichier);
  147.                  break;
  148.              case 'd':
  149.                 effaceutilisateur(fichier);
  150.           break;
  151.          case 'l':
  152.                 listeutilisateur(fichier);
  153.           break;
  154.          }
  155. }
  156. int main(int ac, char **av)
  157. {
  158. int choixoption;
  159. extern int opterr;
  160. opterr=0;
  161.     nbrconf(ac);
  162. choixoption=woptions(ac,&av);
  163. fichierlu(av[2]);
  164. priseoption(choixoption,av[2]);
  165. }


 
MERCI par avance


Message édité par mayapour le 23-06-2006 à 16:17:58
mood
Publicité
Posté le 22-06-2006 à 22:34:37  profilanswer
 

n°1393379
Sve@r
Posté le 23-06-2006 à 00:59:48  profilanswer
 

Hum... un peu compliqué.
Bon, avant toute chose, il faut savoir qu'une liste chaînée n'est utile que si tu dois insérer des éléments au-milieu d'autres. Avec une liste chaînée, tu crées un nouvel élément puis tu mets à jour les liens.
Si ton élément vient s'insérer après les autres, une liste chaînée marchera mais n'est vraiment pas utile et peut avantageusement être remplacée par un tableau que tu alloues et réalloue avec realloc dès que tu l'as remplis...
 
Remarque annexe: c'est pas très propre de mettre des "exit" dans des fonctions autre que "main"


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1393734
franceso
Posté le 23-06-2006 à 15:42:59  profilanswer
 

Sve@r a écrit :

Bon, avant toute chose, il faut savoir qu'une liste chaînée n'est utile que si tu dois insérer des éléments au-milieu d'autres. Avec une liste chaînée, tu crées un nouvel élément puis tu mets à jour les liens.
Si ton élément vient s'insérer après les autres, une liste chaînée marchera mais n'est vraiment pas utile et peut avantageusement être remplacée par un tableau que tu alloues et réalloue avec realloc dès que tu l'as remplis...


Effectivement, mais je pense que dans ce cas, la liste chaînée se justifie pour les suppressions d'éléments (fonction effaceutilisateur).
 
mayapour> Ta définition de la structure Element me paraît pas mal, mais je ne comprends pas pourquoi val est un int et pas un my_passwd.
Tu devrais maintenant te construire une petite bibliothèque de fonctions permettant de manipuler tes listes chaînées (ajout, suppression, recherche). On t'aidera si tu as des problèmes pour ça.
Ensuite, il sera simple de reprendre tes fonctions existantes et les primitives de manipulation de listes pour faire ce que tu veux.
 
PS: utilise des balises code pour poster tes programmes stp.
 
 
EDIT: j'avais pas vu le topic doublon :spamafote:

Message cité 1 fois
Message édité par franceso le 23-06-2006 à 15:46:50

---------------
TriScale innov
n°1393818
Sve@r
Posté le 23-06-2006 à 16:53:00  profilanswer
 

franceso a écrit :

Effectivement, mais je pense que dans ce cas, la liste chaînée se justifie pour les suppressions d'éléments (fonction effaceutilisateur).


Exact. J'avais juste survolé le code sans fait gaffe à cette fonction. Effectivement, s'il y a insertion ou suppression d'un élément intermédiaire, la liste chaînée se justifie.
 

franceso a écrit :

mayapour> Ta définition de la structure Element me paraît pas mal, mais je ne comprends pas pourquoi val est un int et pas un my_passwd.
Tu devrais maintenant te construire une petite bibliothèque de fonctions permettant de manipuler tes listes chaînées (ajout, suppression, recherche). On t'aidera si tu as des problèmes pour ça.
Ensuite, il sera simple de reprendre tes fonctions existantes et les primitives de manipulation de listes pour faire ce que tu veux.


Très bonnes remarques. Je vais rajouter les miennes
1) en général, une structure se nomme conventionnellement "s_qqchose" => struct s_passwd" au lieu de "struct passwd"
 
2) utiliser "typedef" permet de ne plus être obligé de mettre "struct" chaque fois que tu veux avoir une variable de type "struct s_passwd"

typedef struct {
       char          pw_name[255];   /* user name */
       char          pw_passwd[255]; /* password */
       char          pw_shell[64];   /* default shell */
} t_passwd;


Ensuite, au-lieu de créer des variables de type "struct s_passwd", tu crées des variables de type "t_passwd" mais qui s'emploient de la même manière
 
3) après avoir défini ton type "t_elem" te permettant de manipuler un élément de ta liste, il est souvent judicieux de créer un type "t_liste" te permettant de manipuler toute ta liste entière.
Ce type (pouvant être vu comme "poignée de ta liste" ) contiendra évidemment un pointeur sur le premier élément, éventuellement un pointeur sur le dernier, un pointeur sur l'élément en cours de traitement, etc (tout ce qu'il peut te paraître utile d'avoir).
Ensuite, dans ton main, tu définis un "t_liste liste" et tu initialises tous ses pointeurs à NULL (autant créer une fonction "void ListeInit" pour faire cela) puis, dès que tu veux passer ta liste à une fonction quelconque, tu lui passes "&liste" et ta fonction recevant un pointeur de type "t_liste *" pourra, à partir de ce pointeur, manipuler à son grès chacun des éléments de ta liste.
 
En faisant comme Francesco le dit, en créant toute une foule de fonctions te permettant de manipuler un élément, ou une liste complète, tu te rapproches de la philosophie "objet" (un type + des fonctions pour le manipuler). Une fois que tes fonctions sont bien solides, la finalisation devient très simple.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Liste chainée

 

Sujets relatifs
balayer liste chainéeAlgorithme de permutation de 2 éléments d'une liste simplement chaînée
Liste chainée dans un fichierProblème de gestion de liste chainée
Pointeurs intelligents et liste chainée[RESOLU] PROB liste chainée d'objet push_back()
[C++ débutant] Liste chaînée, suite des problemes :DListe chainée
[Liste Chainée]tête de liste chainée
Plus de sujets relatifs à : Liste chainée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR