Supprimer un element d'une liste chainee

Supprimer un element d'une liste chainee - C - Programmation

Marsh Posté le 17-10-2007 à 00:34:07    

Bonjour,

Code :
  1. # include <stdio.h>
  2. # include <string.h>
  3. # include <stdlib.h>
  4. struct list  {
  5.   char word [ 50 ];
  6.   struct list * next;
  7.   };
  8. void Printlist (struct list * );
  9. void mdelete( struct list *p,
  10.               struct list *i,
  11.               struct list **start,
  12.               struct list **last)
  13. {
  14.     if(p) p->next = i->next;
  15.     else *start = i->next;
  16.     if(i==*last && p) *last = p;
  17. }
  18. int main ( void )
  19. { int choice;
  20.   struct list *start, *p;
  21.   start = malloc ( sizeof (struct list));
  22.   start->next = NULL;
  23. do {
  24.     printf("\n\n\t 1.  Add a word" );
  25.     printf("\n\t 2.  Delete a word" );
  26.     printf("\n\t 3.  Search for and display" );
  27.     printf("\n\t 4.  Display data in queue order" );
  28.     printf("\n\t 5.  Quit" );
  29.     printf("\n\n\t Enter your choice : " );
  30.     scanf("%i", & choice);
  31.     if ( choice == 1 ) {
  32.         for(p = start; p->next != NULL; p = p->next){}
  33.         p->next = malloc (sizeof(struct list));
  34.         p->next->next = NULL;
  35.         printf("\n\tEnter the word to add : " );
  36.         scanf("%s", p->word);
  37.      }
  38.     if ( choice == 2 ) {
  39.         printf("\n\tEnter the word to delete : " );
  40.         scanf("%s", p->word);
  41.         mdelete(p->word,x->start,x->last);   
  42.         Printlist ( start );
  43.         }
  44.     if ( choice == 4 ) {
  45.         Printlist ( start );
  46.         }
  47.     } while ( choice != 5 );
  48. return 0;
  49. }
  50. void Printlist (struct list * x)
  51. {
  52.   int v = 1;
  53.   while ( x != NULL ) {
  54.         printf ("\n\tElement %i is : %s \n", v++, x->word);
  55.         x = x->next;
  56.         }
  57. }


 
Je ne sais pas comment appeller la fonction mdelete pour que celle-ci supprime un element deja entre par l'utilisateur.
 
Quand le choix 2 est executee, mdelete() doit etre appelle pour qu'elle supprime un mot. Mais j'ai un probleme en appellant cette fonction.
 
Si quelqu'un me guider sur comment organiser les choses dans if ( choice == 2 ) {}
 
Merci.

Reply

Marsh Posté le 17-10-2007 à 00:34:07   

Reply

Marsh Posté le 17-10-2007 à 01:40:30    

Il manquerait pas un argument dans ton appel à mdelete ?

Reply

Marsh Posté le 17-10-2007 à 02:06:59    

Oui mais c'est pas comme ca que je devrais l'appeller.
 
Comment je devrais appeller mdelete, et quelles sont les arguments a mettre ? Car j'ai des erreurs quand je compile.
 
Merci de votre aide

Reply

Marsh Posté le 17-10-2007 à 02:07:06    


test.c: In function ‘main’:
test.c:41: error: ‘x’ undeclared (first use in this function)
test.c:41: error: (Each undeclared identifier is reported only once
test.c:41: error: for each function it appears in.)
test.c:41: warning: passing argument 1 of ‘mdelete’ from incompatible pointer type
test.c:41: error: too few arguments to function ‘mdelete’

Reply

Marsh Posté le 17-10-2007 à 02:12:33    

Je sais qu'il faudrait y mettre 4 arguments, mais que seront ces arguments? car je suis un peu perdu avec tout ses pointers.

Reply

Marsh Posté le 17-10-2007 à 02:19:34    

Ben, il manque un paramètre, et je suis pas sûr de ta procédure mdelete, mais, mdelete(p, start, last) devrais faire l'affaire et le i ne serait pas un parametre de la procédure mdelete mais une variable. Mais je suis pas sûr, il faut que je relise, désolé.  

Reply

Marsh Posté le 17-10-2007 à 02:24:12    

Code :
  1. If (p) .... //


 
Cette instruction veut dire "si le pointeur p n'est pal nul", nest- ce pas ?

Reply

Marsh Posté le 17-10-2007 à 02:33:37    

Oui c'est ca...

Reply

Marsh Posté le 17-10-2007 à 02:43:20    

fait la recherche du mot dans la liste je présume et que donnes les paramètres effectifs de la procédure mdelete.
 
Une recherche dans une liste chaîné non ordonnée, je crois vaguement, plus ou moins formellement donc, que c'est un parcours des élément O=n si je ne m'abuse.

Reply

Marsh Posté le 17-10-2007 à 02:53:42    

perso, j'aime bien réserver les boucle for pour les conditions les mieux adaptées, mais j'ai l'abitude d'écrire en Ada, mais un for ou un while avec l'index i qui parcoure la liste est du tdonne p, start, last et i, dans les bonne case.

Reply

Marsh Posté le 17-10-2007 à 02:53:42   

Reply

Marsh Posté le 17-10-2007 à 02:57:33    

Au fur et a mesure que tu compares i->word avec P->word tu fais i = i->next,

Reply

Marsh Posté le 17-10-2007 à 03:12:31    

j'ai pas trop compris ta reponse... donc c'est quoi la solution?

Reply

Marsh Posté le 17-10-2007 à 03:17:16    

une boucle while ou for, à toi de choisir.

Reply

Marsh Posté le 17-10-2007 à 03:24:38    

for (i->word, p->word != NULL, i = i->next) {}
mdelete (p,start,last,i);
 
 
cela ferais-t-il l'affaire ?
 
 

Reply

Marsh Posté le 17-10-2007 à 03:38:28    

for (i-= start , p != NULL, i = i->next)  
{
if (i->word == p->word) break;
}
mdelete (p,i,start,last);
 
 
si break te permet de sortir de la boucle.
 
il faut que tu declare i dans la partie declarative du la fonction main

Reply

Marsh Posté le 17-10-2007 à 03:44:45    

tu fais quoi au juste en français dans ta procedure mdelete ?

Reply

Marsh Posté le 17-10-2007 à 03:48:44    

Citation :

il faut que tu declare i dans la partie declarative du la fonction main


 

Code :
  1. struct list *start, *p;


 
Comme ca ?

Reply

Marsh Posté le 17-10-2007 à 03:53:33    

Le compileur m'affice quelques erreurs
 

Code :
  1. strucc.c:53: error: `last' undeclared (first use in this function)
  2. strucc.c:53: error: (Each undeclared identifier is reported only once
  3. strucc.c:53: error: for each function it appears in.)
  4. strucc.c:53: warning: passing arg 3 of `mdelete' from incompatible pointer type

Reply

Marsh Posté le 17-10-2007 à 03:58:47    

il faut que tu déclares i comme tu as déclaré start et p, déclares last aussi.
 
Mais après j'ai un problème avec la fonction mdelete, je comprend pas ce que tu veux faire.
 
 
 
En français alors ?
 
 
Et il faut que tu fasse suivre last dans "choice 1".

Reply

Marsh Posté le 17-10-2007 à 04:02:00    

un '*' c'est un pointeur, une adresse, bref, un "**" c'est quoi, un pointeur sur un pointeur ?
 

Reply

Marsh Posté le 17-10-2007 à 04:10:49    

J'appelle desormais mdelete comme ceci

Code :
  1. mdelete(p,i,&start,&last);


 
Le code compile mais il y a une seg fault quand j'entre le mot a supprimer... est ce que c'est un probleme dans scanf() ?  
 
 

Citation :

Et il faut que tu fasse suivre last dans "choice 1".


 
Peux-tu etre plus precis ?

Reply

Marsh Posté le 17-10-2007 à 04:16:26    

A, ben non, c'est p last, donc tu affecte p à last avant de saisir ton mot à supprimer.
 
Mais j'avais pas vu, c'est pas dans l'ordre dans "choice 1"

Reply

Marsh Posté le 17-10-2007 à 04:17:58    

J'essai d'écrire le code, mais il est tard déjà, A+

Reply

Marsh Posté le 17-10-2007 à 04:32:41    

Code :
  1. int main ( void )
  2. { int choice;
  3.  struct list *start, *p, *i, *last ;
  4.  start = malloc ( sizeof (struct list));
  5.  start->next = NULL;
  6. do {
  7.    printf("\n\n\t 1.  Add a word" );
  8.    printf("\n\t 2.  Delete a word" );
  9.    printf("\n\t 3.  Search for and display" );
  10.    printf("\n\t 4.  Display data in queue order" );
  11.    printf("\n\t 5.  Quit" );
  12.    printf("\n\n\t Enter your choice : " );
  13.    scanf("%i", & choice);
  14.    if ( choice == 1 ) {
  15.      printf("\n\tEnter the word to add : " );
  16.      scanf("%s", p->word);
  17.      for(p = start; p->next != NULL; p = p->next)
  18.     {
  19.       p->next = malloc (sizeof(struct list));
  20.       p->next->next = NULL;
  21.     }
  22.      last = p->next;
  23.        
  24.     }
  25.    if ( choice == 2 ) {
  26.        printf("\n\tEnter the word to delete : " );
  27.        scanf("%s", p->word);
  28.        mdelete(p, i, &start, &last);  
  29.        Printlist ( start );
  30.        }
  31.    if ( choice == 4 ) {
  32.        Printlist ( start );
  33.        }
  34.    } while ( choice != 5 );
  35. return 0;


 
Mais il génère une erreur à l'execution.

Reply

Marsh Posté le 17-10-2007 à 04:45:31    

Code :
  1. # include <stdio.h>
  2. # include <string.h>
  3. # include <stdlib.h>
  4. struct list  {
  5.  char word [ 50 ];
  6.  struct list * next;
  7.  };
  8. void Printlist (struct list * );
  9. void mdelete( struct list *p,
  10.              struct list *i,
  11.              struct list **start,
  12.              struct list **last)
  13. {
  14.    if(p) p->next = i->next;
  15.    else *start = i->next;
  16.    if(i==*last && p) *last = p;
  17. }
  18. int main ( void )
  19. { int choice;
  20.  struct list *start, *p, *i, *last ;
  21.  start = malloc ( sizeof (struct list));
  22.  start->next = NULL;
  23. do {
  24.    printf("\n\n\t 1.  Add a word" );
  25.    printf("\n\t 2.  Delete a word" );
  26.    printf("\n\t 3.  Search for and display" );
  27.    printf("\n\t 4.  Display data in queue order" );
  28.    printf("\n\t 5.  Quit" );
  29.    printf("\n\n\t Enter your choice : " );
  30.    scanf("%i", & choice);
  31.    if ( choice == 1 ) {
  32.      printf("\n\tEnter the word to add : " );
  33.      scanf("%s", p->word);
  34.      for(p = start; p->next != NULL; p = p->next)
  35.     {
  36.       
  37.     }
  38.      p->next = malloc (sizeof(struct list));
  39.      p->next->next = NULL;
  40.      last = p->next;
  41.        
  42.    }
  43.    if ( choice == 2 ) {
  44.      
  45.      
  46.      printf("\n\tEnter the word to delete : " );
  47.      scanf("%s", p->word);
  48.     for (i = start ; p != NULL; i = i->next)  
  49.       {
  50.         if (i->word == p->word) break;
  51.       }
  52.        mdelete(p, i, &start, &last);  
  53.        Printlist ( start );
  54.    }
  55.    if ( choice == 4 ) {
  56.      Printlist ( start );
  57.    }
  58. } while ( choice != 5 );
  59. return 0;
  60. }
  61. void Printlist (struct list * x)
  62. {
  63.  int v = 1;
  64.  while ( x != NULL ) {
  65.        printf ("\n\tElement %i is : %s \n", v++, x->word);
  66.        x = x->next;
  67.        }
  68. }


 
 
Pour copier coller, double clique dans l'encadrement du code, ça efface les numéro de ligne.
 
 
Mais ça marche pas encore.

Message cité 1 fois
Message édité par Profil supprimé le 17-10-2007 à 04:45:50
Reply

Marsh Posté le 17-10-2007 à 04:54:48    

[:le kneu]  
 [:blueflag]  
Bon désolé pour l'aide je vais dodoter, je repasserai demain (enfin tout à l'heure).
Pour commencer utilise fgets au lieu de scanf, ce sera déjà ça de gagné...


---------------
You get so used to things the way they are. And I've always been alone. I guess that makes me lonely.
Reply

Marsh Posté le 17-10-2007 à 16:19:32    

vituoz a écrit :

Bonjour,

Code :
  1. # include <stdio.h>
  2. # include <string.h>
  3. # include <stdlib.h>
  4. struct list  {
  5.   char word [ 50 ];
  6.   struct list * next;
  7.   };
  8. void Printlist (struct list * );
  9. void mdelete( struct list *p,
  10.               struct list *i,
  11.               struct list **start,
  12.               struct list **last)
  13. {
  14.     if(p) p->next = i->next;
  15.     else *start = i->next;
  16.     if(i==*last && p) *last = p;
  17. }
  18. int main ( void )
  19. { int choice;
  20.   struct list *start, *p;
  21.   start = malloc ( sizeof (struct list));
  22.   start->next = NULL;
  23. do {
  24.     printf("\n\n\t 1.  Add a word" );
  25.     printf("\n\t 2.  Delete a word" );
  26.     printf("\n\t 3.  Search for and display" );
  27.     printf("\n\t 4.  Display data in queue order" );
  28.     printf("\n\t 5.  Quit" );
  29.     printf("\n\n\t Enter your choice : " );
  30.     scanf("%i", & choice);
  31.     if ( choice == 1 ) {
  32.         for(p = start; p->next != NULL; p = p->next){}
  33.         p->next = malloc (sizeof(struct list));
  34.         p->next->next = NULL;
  35.         printf("\n\tEnter the word to add : " );
  36.         scanf("%s", p->word);
  37.      }
  38.     if ( choice == 2 ) {
  39.         printf("\n\tEnter the word to delete : " );
  40.         scanf("%s", p->word);
  41.         mdelete(p->word,x->start,x->last);   
  42.         Printlist ( start );
  43.         }
  44.     if ( choice == 4 ) {
  45.         Printlist ( start );
  46.         }
  47.     } while ( choice != 5 );
  48. return 0;
  49. }
  50. void Printlist (struct list * x)
  51. {
  52.   int v = 1;
  53.   while ( x != NULL ) {
  54.         printf ("\n\tElement %i is : %s \n", v++, x->word);
  55.         x = x->next;
  56.         }
  57. }


 
Je ne sais pas comment appeller la fonction mdelete pour que celle-ci supprime un element deja entre par l'utilisateur.
 
Quand le choix 2 est executee, mdelete() doit etre appelle pour qu'elle supprime un mot. Mais j'ai un probleme en appellant cette fonction.
 
Si quelqu'un me guider sur comment organiser les choses dans if ( choice == 2 ) {}
 
Merci.


 
C'est toi qui a écrit la fonction mdelete ? Dans ce cas tu devais avoir une logique en l'écrivant. Donc tu devrais savoir l'utiliser !!!!
Déjà son premier paramètre c'est un pointeur sur un "struct list" donc tu peux absolument pas lui passer p->word qui est un pointeur sur un char...
 
Moi, je te conseillerais de bien concevoir tes objets car c'est peut-être du temps passé au départ mais ça simplifie grandement la vie ensuite. Déjà, conceptuellement parlant, le truc qui stocke un mot et un pointeur sur le truc suivant c'est pas une "liste" mais un "élément de ta liste". Donc si tu l'appelais "struct elem" peut-être que tu verrais mieux ce que tu manipules.
Ensuite, ben tu pourrais très bien concevoir un truc pour manipuler ta liste. Ce truc qui pourrait être un "struct list" contiendrait par exemple un pointeur sur le premier élément (voire un pointeur sur le dernier si tu en as envie ou encore le nombre d'éléments ou autre). Ensuite il te suffirait de passer à chaque fonction l'adresse de ce "struct list" donc tes fonctions recevraient un "struct list *" et 1) rien qu'avec ce pointeur tu aurais accès au premier élément de ta liste et aussi au dernier (tu évites donc le "start" et le "last" ) et 2) tu n'irais pas te débattre avec des "**" à profusion dans lesquels tu n'arrives pas à t'y retrouver et tu rends ton code illisible.
 
Autre détail => Dans ton main, tu commences par initialiser "start" puis tu travailles ensuite sur p->next (donc tu travailles sur 2 éléments à la fois). Tu te compliques trop la vie et tu ouvres la porte aux bugs. Apprends à découper tes tâches de base en fonctions puis appelle les fonctions qu'il faut quand il faut
 
Dernier détail => les commentaires ne sont pas une légende urbaine => ils existent (et en mettre te permettra de garder en tête ton idée directrice)
 
Tiens, juste pour l'exemple, voici les structures telles que je les vois et la réécriture de ta fonction mdelete telle que je l'ai comprise

Code :
  1. struct elem {
  2.    char word[50];
  3.    struct elem *next;
  4. };
  5.  
  6. struct list {
  7.    struct elem *first;
  8.    struct elem *last;
  9. };
  10.  
  11. void init(struct list *liste)
  12. {
  13.     liste->first=NULL;
  14.     liste->last=NULL;
  15. }
  16.  
  17. // Fonction qui efface un élément de la liste
  18. void delete(struct list *liste, struct elem *elem)
  19. {
  20.    struct elem *cur;
  21.    struct elem *prev;
  22.  
  23.    // Si la liste est vide il n'y a rien à effacer
  24.    if (liste->first == NULL) return;
  25.  
  26.    // Positionnement des deux éléments "prev" et "cur" sur l'élément juste avant et sur l'élément à effacer
  27.    for (cur=liste->first, prev=NULL; cur != elem; prev=cur, cur=cur->next);
  28.  
  29.    // Si l'élément précédent existe
  30.    if (prev)
  31.        // L'élément précédent prend l'adresse du suivant
  32.        prev->next=cur->next;
  33.    else
  34.        // L'élément à supprimer était le premier => celui-ci change
  35.        liste->first=cur->next;
  36.  
  37.    // Si l'élément à effacer était le dernier
  38.    if (cur->next == NULL)
  39.        // Le dernier élément de la liste change
  40.        liste->last=cur;
  41.  
  42.    // L'élément à effacer est supprimé
  43.   free(elem);
  44. }
  45.  
  46. // Fonction qui efface un mot de la liste
  47. void mdelete(char *word, struct list *liste)
  48. {
  49.    struct elem *cur;
  50.  
  51.    // Recherche du mot dans la liste
  52.    for (cur=liste->first; cur != NULL; cur=cur->next)
  53.    {
  54.          if (strcmp(cur->word, word) == 0)
  55.             break;
  56.    }
  57.  
  58.    // Si l'élément contenant le mot a été trouvé
  59.    if (cur)
  60.        // Il est supprimé de la liste
  61.       delete(liste, cur);
  62. }

   
 
Le reste à l'avenant (fonction pour créer et remplir un élément, pour insérer un élément, pour afficher un élément, pour afficher toute la liste etc...)
 
Ensuite, l'écriture du programme est hyper simple

Code :
  1. int main()
  2. {
  3.    struct list liste;
  4.  
  5.    // Initialisation de la liste
  6.    init(&liste);
  7.  
  8.    // Menu
  9.    ...
  10.  
  11.    // Evaluation du menu
  12.    switch(...)
  13.    {
  14.         case 1:
  15.               ...
  16.               break;
  17.         case 2: // Suppression d'un mot
  18.            <... stockage du mot à supprimer ...>
  19.            mdelete(mot, &liste);
  20.            break;
  21.         ...
  22.     }
  23. }


 
 
 
Pas étonnant => le code est aussi pourri que celui de vituoz. Arrêtez de vouloir tout faire dans le main et de taper du code à l'arrache sans comprendre où vous allez !!!


Message édité par Sve@r le 18-10-2007 à 10:34:01

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

Marsh Posté le 17-10-2007 à 18:19:10    

Merci pour ta reponse. Mais il y a bcp de bugs...
 
Il y a un probleme avec la fonction init de la ligne 11. Qu'est ce que "s_list"? serait-elle "list" tout court ?
 

Code :
  1. struc.c:15: warning: "struct s_list" declared inside parameter list
  2. struc.c:15: warning: its scope is only this definition or declaration, which is probably not what you want
  3. struc.c:16: error: two or more data types in declaration of `init'
  4. struc.c: In function `init':
  5. struc.c:17: error: dereferencing pointer to incomplete type
  6. struc.c:18: error: dereferencing pointer to incomplete type


 
 
Dans la fonction delete.  

Code :
  1. struc.c: In function `delete':
  2. struc.c:35: error: `list' undeclared (first use in this function)


 
Est ce que dans les lignes 35 et 40, tu as voulu ecrire "liste" au lieu de "list" ?
 
 
Autre question, pourquoi n'as tu pas utilise d'allocation dynamique ?
 
Qu'en est-il du stockage de mot dans la fonction main ?
 
 
 
 
 

Reply

Marsh Posté le 17-10-2007 à 18:20:46    

Quel variable doit-il y a voir pour le stockage de mot ? est ce que ca doit etre un pointeur ? ou bien la variable "word" ?

Code :
  1. printf("\n\tEnter the word to delete : " );
  2.         scanf("%s", word);
  3.         mdelete(word, &liste);

Reply

Marsh Posté le 17-10-2007 à 20:22:08    

vituoz a écrit :

Merci pour ta reponse. Mais il y a bcp de bugs...
 
Il y a un probleme avec la fonction init de la ligne 11. Qu'est ce que "s_list"? serait-elle "list" tout court ?


Oui, j'ai l'habitude de nommer mes structures "s_" et donc quand j'ai tapé mon code cette habitude est ressortie. J'ai rectifié mon post pour corriger les noms
 

vituoz a écrit :

Autre question, pourquoi n'as tu pas utilise d'allocation dynamique ?


Ah ça c'est la fonction "remplirElem()" qui le fera. Tu lui passes en paramètre le mot à stocker et elle alloue la mémoire, stocke le mot et met le pointeur next à NULL et te renvoie un pointeur sur l'élément alloué. Puis une fois ce pointeur en main, tu le passes à la fonction "insereElem()" qui met cet élément à la bonne place dans la liste. Les deux opérations pourraient tout à fait se faire ensemble mais en les séparant, tu peux mieux gérer la modularité de ton programme. Tu peux par exemple avoir une fonction qui insère toujours au début, une autre qui insère toujours à la fin, une 3° qui insère dans l'ordre alphabétique et tu appelles celle que tu veux quand tu veux. Mais bien entendu faut que tu les écrives (je vais pas tout te faire non plus)...
 

vituoz a écrit :

Qu'en est-il du stockage de mot dans la fonction main ?


Le mot qu'on veut enlever ? A toi de déclarer la variable adéquate et la faire remplir par la fonction que tu voudras. Je t'ai tapé un "squelette" de programme pour que tu comprennes l'idée générale de ce genre de truc mais faut quand-même que tu fasses des trucs par toi-même...
 

vituoz a écrit :

Quel variable doit-il y a voir pour le stockage de mot ? est ce que ca doit etre un pointeur ? ou bien la variable "word" ?

Code :
  1. printf("\n\tEnter the word to delete : " );
  2.         scanf("%s", word);
  3.         mdelete(word, &liste);



C'est pas mauvais. Faut juste que tu définisses ta variable "word" comme une variable qui te permet de saisir un mot (donc des lettres) => par exemple char word[50]...


Message édité par Sve@r le 17-10-2007 à 20:23:32

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

Marsh Posté le 17-10-2007 à 22:01:20    

Reste une erreure quand je compile:
 

Code :
  1. struc.c:16: error: two or more data types in declaration of `init'


 
Qu'est ce qui cloche avec la fonction init ?

Code :
  1. void init(struct list *liste)
  2. {
  3.     liste->first=NULL;
  4.     liste->last=NULL;
  5. }

Reply

Marsh Posté le 17-10-2007 à 22:34:27    

C'est la structure d'avant qui n'est pas terminee avec un point virgule ;

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed