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

  FORUM HardWare.fr
  Programmation

  [C] Listes chainées

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[C] Listes chainées

n°14063
Evadream -​jbd-
Posté le 13-02-2001 à 13:33:18  profilanswer
 

D'abord voici mon typedef  
 
typedef struct art
 {
        struct art *suivant;
        char *nom;
        char *ref;
        double prix;
        int reste;
        }article;
 
et la partie de mon code qui est tres laide :
 
article* cherche_place(article *t, article* o)  //t est la tete de ma liste et o un article à insérer dans ma liste et je retourne un pointeur sur un article, soit une adresse.
   {
   article *lire=t;
 
   while(lire!=NULL)
    {
      if(strcmp((*lire).nom,(*o).nom)>0)
       {
        return lire;
        }
        lire=(*lire).suivant;      
    }
   getch();
   }
 
Ce que je veux, c'est me positionner n'importe ou ds ma liste chainée. Des que je trouve ((*lire).nom,(*o).nom)>0, je veux sortir de mon if ET de mon while. Ainsi, je retourne l'adresse de lire et donc la position ds ma liste, non ?
 
Le pb, c qd des que je rentre dans mon if, je recontre return, ce qui fait sortir de mon if et rerentrer dans mon while non ?
 
Bon, soyez indulgent, je debute. Le but est d'insérer des élements dans un tableau directement à la bonne place ( ordre alphabétique ). Je ne veux pas tout mettre à la queue et ensuite classer.
 
Merci d'avance !

mood
Publicité
Posté le 13-02-2001 à 13:33:18  profilanswer
 

n°14066
jupiler
Un cousin...
Posté le 13-02-2001 à 13:39:02  profilanswer
 

le return te fait sortir de la fonction cherche_place()
 
ensuite on n'écrit pas (*lire).nom mais lire->nom
donc à changer à tous les endroits où tu cherches à accéder
à un élément d'une structure pointée.
 
fais les modifs et reteste
 
getch(), c'est quoi???
 

 


--Message édité par jupiler--

n°14067
Evadream -​jbd-
Posté le 13-02-2001 à 13:40:57  profilanswer
 

ah oui, je suis avec borland, getch() <=> getchar() il me semble nop ?

n°14068
Evadream -​jbd-
Posté le 13-02-2001 à 13:43:35  profilanswer
 

Ca ne change pas, mais je pense que c'est plutot du coté de l'algo que ca va pas non ?

n°14070
jupiler
Un cousin...
Posté le 13-02-2001 à 13:51:35  profilanswer
 

l'algo me semble bon, sauf que je ne vois pas à quoi sert le getch() et qu'il faut que tu ajoutes "return null" à la fin de la fonction

n°14078
BENB
100% Lux.
Posté le 13-02-2001 à 14:06:17  profilanswer
 

Le return sort de la fct, meme un break sortirait de la boucle me semble-t-il... mais effectivment c'est laid...
Utilise des variables temporaires (en C++ des bool, en C des char ou des short)
 
result = NULL;  
do
{
 exitCondition = strcmp(lire->nom,o->nom);
 if(exitCondition)
  result = lire;
 lire = lire->suivant;
}
while(lire!=NULL && !exitcondition)
 
 return result;

n°14080
Evadream -​jbd-
Posté le 13-02-2001 à 14:11:04  profilanswer
 

ok merci. Je vais voir ca.
 
J'ai une autre erreur, cette fois d'allocation de mémoire :
 
void preinsert(article *t, article *o)
   {
   article* sauve=o;
   o->suivant=t;
   t->suivant=sauve; // c'est la que ca merde
   }
 
Une ( autre ) idée ? :)

n°14089
jupiler
Un cousin...
Posté le 13-02-2001 à 14:26:47  profilanswer
 

euh, c'est sensé faire quoi?

n°14097
Evadream -​jbd-
Posté le 13-02-2001 à 14:36:47  profilanswer
 

mdr, hum. Euh normalement ca serait d'insérer mon article dans ma lite juste apres t ( qui n'est pas la tete mais est l'adresse retourne par cherche place ).
 
Pour insérer mon article ds la liste entre 2 articles A et B pour avoir ca : A | mon_article | B ( A = t, mon_article= o B = A->suivant )
 
je dois sauver A->suivant
               Faire en sorte que A->suivant pointe vers mon_article  
               Et faire en sorte que mon_article pointe vers B soit A->suivant.

 

--Message édité par Evadream -jbd---

n°14100
wouatouwou​atou
Posté le 13-02-2001 à 14:43:42  profilanswer
 

deja ton getch() sert a koi ici ?? c bof de le mettre ici meme si c pour un debuggage :)
 
essaie une boucle du genre:
 
 
lire=t;
if ( o != null )
  while ( ( lire != null ) && ( strcmp((*lire).nom,(*o).nom)<=0 ) )
   lire = (*lire).suivant;
 
return lire;


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
mood
Publicité
Posté le 13-02-2001 à 14:43:42  profilanswer
 

n°14101
wouatouwou​atou
Posté le 13-02-2001 à 14:50:18  profilanswer
 

jai pas essaye alors si ca marche tant mieux :D
 
Au fait, si tu veux inserer un elt dans ta liste... tu peux faire:
 
(*o).suivant = (*liste).suivant;
(*liste).suivant = o;
 
Mais, fait aussi un test avant sur la validité de tes variables !!!!
du style:  
 
if ( ( temp == null ) || (liste == null ) )
  return;
 
:D
J'espere que c bon ce ke je te dis paske je peux pas le tester ici alors... :D:D


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14102
verdoux
And I'm still waiting
Posté le 13-02-2001 à 15:02:27  profilanswer
 

Evadream -jbd- a écrit a écrit :

ok merci. Je vais voir ca.
 
J'ai une autre erreur, cette fois d'allocation de mémoire :
 
void preinsert(article *t, article *o)
   {
   article* sauve=o;
   o->suivant=t;
   t->suivant=sauve; // c'est la que ca merde
   }
 
Une ( autre ) idée ? :)




 
Faut pas mettre o->suivant = t-> suivant ?

n°14104
Evadream -​jbd-
Posté le 13-02-2001 à 15:04:04  profilanswer
 

C'est ce que je me suis dit en postant, mais ca marche tjs pas ;)
 
je vais réfléchir à toutes vos indications

n°14109
Toxin
Carpe ★★ Vitam
Posté le 13-02-2001 à 15:08:59  profilanswer
 

T'es sûr que la structure pointée par t est allouée ????


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14112
wouatouwou​atou
Posté le 13-02-2001 à 15:14:22  profilanswer
 

Verdoux> Sisi, je pense aussi :) (cf. mon post precedent)
 
A mon avis, t'as du oublier un chtit malloc qqpart :D


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14113
jupiler
Un cousin...
Posté le 13-02-2001 à 15:14:56  profilanswer
 

excellente remarque!
 
sinon, suffit de mettre:
 
o->suivant=t->suivant (o recupère B comme suivant)
t->suivant = o (t recupère o comme suivant)
 
mais il est primordiale que t et o aient été alloués

n°14114
wouatouwou​atou
Posté le 13-02-2001 à 15:15:40  profilanswer
 

p.s: D'où le petit test que je te disais plus haut :D


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14116
Evadream -​jbd-
Posté le 13-02-2001 à 15:17:10  profilanswer
 

lorsque mes articles sont crées je fait ca :
 
objet=(article*)malloc(sizeof(article));
 
Mais je pense avoir un tit prob, vu que ds mon main j'ai un tete=NULL; qui traine, je vais voir ca.
 
Merci encore !

n°14122
Toxin
Carpe ★★ Vitam
Posté le 13-02-2001 à 15:44:10  profilanswer
 

"ds mon main j'ai un tete=NULL" :D:D:D


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14123
Evadream -​jbd-
Posté le 13-02-2001 à 15:45:42  profilanswer
 

rhooo :)

n°14125
wouatouwou​atou
Posté le 13-02-2001 à 15:54:04  profilanswer
 

bouuuuhhhh :lol:


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14126
Robinmaste​rs
Posté le 13-02-2001 à 16:02:12  profilanswer
 

sous borland c++ sous windowd si tu mets un getch()en fin de prog
parfois pour faire une sorte de pause  
-> getch() = attente d'une saisie de char au clavier
 
si pas de getch alors la fenetre dos se ferme et on voit rien


---------------
-Hassan Cehef --> C'est possible -Roberttripoux --> Les bons comptes font les bons amis
n°14128
Evadream -​jbd-
Posté le 13-02-2001 à 16:06:09  profilanswer
 

BENB, je ne comprends pas le : if(exitCondition)
 
exitCondition est <0 == 0 ou >0, mais qd rentre t'on ds le if ?

n°14131
wouatouwou​atou
Posté le 13-02-2001 à 16:07:20  profilanswer
 

c bien ce ke je pensais... Mais moi je prefere des println() ou printf() (jsais plus c koi le bon en C :D )
 
Car pour le debuguage, rien de tel !!!!
les getch() & Co. c'est bof car si tas une erreur avant.. ben tu vois rien. et tu sais pas ou c en +.
Pi si tu veux voir le resultat simplement, ben le printxx() le fait plutot bien. :)


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14132
wouatouwou​atou
Posté le 13-02-2001 à 16:08:53  profilanswer
 

de quel if tu parles ?? :??:


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14134
Evadream -​jbd-
Posté le 13-02-2001 à 16:10:39  profilanswer
 

cf post de BENB :
 
result = NULL;  
do  
{  
exitCondition = strcmp(lire->nom,o->nom);  
if(exitCondition)  
  result = lire;  
lire = lire->suivant;  
}  
while(lire!=NULL && !exitcondition)  
 
return result;

n°14136
wouatouwou​atou
Posté le 13-02-2001 à 16:23:06  profilanswer
 

ben ... je crois que le if en C cest TRUE si different de zero
alors sa condition marche pas tout a fait... car si cest negatif sa sort quand meme !!! :D
 
Bref, essaie mon truc (cf. mon post plus haut) ca devrais marcher... en fin je crois :D:D


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14141
Toxin
Carpe ★★ Vitam
Posté le 13-02-2001 à 16:33:41  profilanswer
 

C'est pas une hypothèse, c'est sûr.
 
tu peux même définir
#define NOK 0
#define OK  !NOK
 
si tu veux.


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14145
Evadream -​jbd-
Posté le 13-02-2001 à 16:45:04  profilanswer
 

Je suis repartit de zéro pour y voir plus clair.
 
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
#include<string.h>
 
typedef struct art
   {
   struct art *suivant;
   char *nom;
   char *ref;
   double prix;
   int reste;
   }article;
 
 
 
article* creer();
article* detection(article* t, article* o);
void inserer(article* t,article* o);
void preinsert(article* t, article* o);
 
 
 
void main()
   {
   article* tete;
   article* objet;
   char rep='o';
   //creation de la liste
   tete=NULL;
 
   printf("Creation d'une liste chainee\n" );
   getch();
 
   while(rep=='o')
      {
      objet=creer();
      clrscr();
      printf("Donner son nom : " );
      scanf(" %s", objet->nom);
      inserer(tete,objet);
      printf("\ncontinuer ? :" );
      scanf(" %c", &rep);
      }
   getch();
   }
 
 
 
article* creer()
   {
   article* objet;
   objet=(article*)malloc(sizeof(article));
   objet->nom=(char*)malloc(sizeof(char));
   objet->ref=(char*)malloc(sizeof(char));
   objet->suivant=NULL;
   return objet;
   }
 
 
void inserer(article* t, article *o)
   {
   article* cursor=detection(t,o);
   preinsert(cursor,o);
   }
 
void preinsert(article *t, article *o)
   {
   o->suivant=t->suivant; // c'est la qu'il y a erreur
   t->suivant = o;  
   }
 
article* detection(article* t, article* o)
   {
   article* lire=t;
   
   if ( o != NULL )
      {
      while ( ( lire != NULL ) && ( strcmp((*lire).nom,(*o).nom)<=0 ) )
       {
        lire = lire->suivant;
        }
      }
      return lire;
   }
 
je ne comprends pas pkoi lorsque j'execute, j'ai ce probleme, pourtant t et o sont allouees non ?
 
Desole de vous prendre le choux

 

--Message édité par Evadream -jbd---

n°14148
Toxin
Carpe ★★ Vitam
Posté le 13-02-2001 à 16:55:14  profilanswer
 

Arf et si t est à NULL comme au début quand ta liste est vide :D
t->suivant=qqchose ça fait du dégât :D
 
Il faut que tu réécrives les cas spécifiques d'insertion dans une liste vide ou d'une insertion en tête.

 

--Message édité par Toxin--


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14152
Evadream -​jbd-
Posté le 13-02-2001 à 17:09:20  profilanswer
 

chuis con.

n°14153
jupiler
Un cousin...
Posté le 13-02-2001 à 17:10:20  profilanswer
 

teste dans preinsert si t est null
 
if (t != NULL)
{
o->suivant=t->suivant;
   t->suivant = o;  
}
else
o->suivant = NULL;

n°14154
Toxin
Carpe ★★ Vitam
Posté le 13-02-2001 à 17:12:10  profilanswer
 

Evadream -jbd- a écrit a écrit :

chuis con.




 
Nan t'es un newbie, tout le monde a fait cette connerie je te rassure.


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14155
Evadream -​jbd-
Posté le 13-02-2001 à 17:13:12  profilanswer
 

;)

n°14157
wouatouwou​atou
Posté le 13-02-2001 à 17:14:30  profilanswer
 

ouaips... pi si tu m'avais écouter en mettant le chtit test de validités de tes variables avant l'insertion, t'aurais pas le pb de Null Pointer Exception !!!
 
Tu peux mettre la contition dans ta fonction inserer()
juste apres la fonction detection().
Du style:  
 
  if ( cursor == null ) // C la tete de la liste
  {
     t = o;
  }
  else
  {
     preinsert(...);
  }
 
Mais faut que tu passes ton article "t" en pointeur de pointeur
(Expression barbare :D )
Sinon, t'auras pas ta liste tout comme i fo :D
Du style :  void inserer(article **t, article *o) { ... }
 
Voilà, pi jespere ke c bon :)


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
n°14237
Toxin
Carpe ★★ Vitam
Posté le 14-02-2001 à 10:27:50  profilanswer
 

Vi mais si t est un article **, c'est *t = o qu'il faut faire.
 
Vu comment tu as développé ton code, il vaut mieux créer une fonction spécifique void inserertete(article **t, article *o) ;
 
L'appel de la fonction quant à lui est inserertete(&t, o) ;

 

--Message édité par Toxin--


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14254
gilou
Modérateur
Modosaurus Rex
Posté le 14-02-2001 à 11:53:29  profilanswer
 

Bon, j'ai repris en corrigeant a vue d'oeuil le code de ton exemple.
Ce devrait avoir cette aspect la pour tourner:
 
#include<stdio.h>  
#include<conio.h>  
#include<alloc.h>  
#include<string.h>  
 
typedef struct art  
   {  
   struct art *suivant;  
   char *nom;  
   char *ref;  
   double prix;  
   int reste;  
   }article;  
 
 
 
article* creer();  
article* detection(article* t, char* nom);  
void inserer(article* t,article* o);  
void preinsert(article* t, article* o);  
 
 
 
int main()  
   {  
   article* tete = NULL;  
   article* objet;  
   char rep;     /* assigne sur ton premier getch */
   char buffer[255];  /* on peut supposer que l'utilisateur taperas des noms moins long */
 
   printf("Creation d'une liste chainee\n" );  
   getch();  
 
   while(rep=='o' )  
      {  
      objet=creer();
      clrscr();  
      printf("Donner son nom : " );  
      /* scanf(" %s", objet->nom); la ca peche: tu n'avais alloue qu'un caractere */
      scanf(" %s", buffer);
      objet->nom = strdup(buffer);
 
      if (!tete)
 tete = objet; /* tu assignes tete la premiere fois */
      else
 inserer(tete, objet);  
 
      printf("\ncontinuer ? :" );  
      scanf(" %c", &rep);  
      }  
   getch();  
 
   /* un peu de clean up de ta liste chainee devrait te faire un bon exercice en plus */
 
   exit (0);
   }  
 
 
 
article* creer()  
   {  
   article* objet;  
   objet = (article*)malloc(sizeof(article));
   if (!object)
     {
       /* tu ecris un message d'erreur ... ou tu apelles une routine ad hoc */
       /* et tu appelles une routine qui desalloue ta structure si tu veux faire propre */
       exit (-1);
     }
   /* maintenant, en sortie de creation, tu seras sur d'avoir un article alloue */
   /* objet->nom=(char*)malloc(sizeof(char)); pas utile a ce stade, a allouer a l'utilisation effective */
   /* objet->ref=(char*)malloc(sizeof(char)); pas utile a ce stade, a allouer a l'utilisation effective */
   objet->nom = NULL;
   objet->ref = NULL;
   objet->suivant = NULL;  
   return objet;  
   }  
 
 
void inserer(article* t, article *o)  
   {  
   article* cursor = detection(t,o->nom);  
   preinsert(cursor,o);  
   }  
 
void preinsert(article *t, article *o)  
   {  
     /* o->suivant = t->suivant; // c'est la qu'il y a erreur  */
     if (t->suivant)
       o->suivant = t->suivant;
     t->suivant = o;  
   }  
 
article* detection(article* t, char *nom)  
{  
  article* lire = t;  
     
  while ( lire && (strcmp(lire->nom, nom)<= 0))  
    lire = lire->suivant;  
 
  return lire;  
}  
 
 
Bon, en fait, ce qui ne va pas, c'est ta fonction detection:
 Si tu trouves, tu renvoies l'element de ta liste chainee deja trouve et si tu trouves pas, tu renvoies NULL.
Ca pose probleme au retour dans inserer qui a pas prevu que ca retourne NULL.
 Je suppose que ce que tu veux faire c'est:  
 
void inserer(article* t, article *o)  
   {  
   article* cursor = detection(t,o->nom); /* o est non NULL et on ne compare que le nom */
 
   if (cursor)
      preinsert(cursor,o);
   else
      {
        cursor = t; /* on se replace en tete */
        while (cursor->suivant) /* on va a la fin de la lc */
             cursor= cursor->suivant;
        cursor->suivant = o;
      }  
   }  
 
A+,
 

 


--Message édité par gilou--


---------------
There's more than what can be linked! --  Le capitaine qui ne veut pas obéir à la carte finira par obéir aux récifs. -- Il ne faut plus dire Sarkozy, mais Sarkozon -- (╯°□°)╯︵ ┻━┻
n°14256
Toxin
Carpe ★★ Vitam
Posté le 14-02-2001 à 12:01:20  profilanswer
 

/* un peu de clean up de ta liste chainee devrait te faire un bon exercice en plus */
 
Oh oui ça être bon !!!!!! En itératif, récursif et récursif terminal tant qu'à faire :D


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
n°14258
gilou
Modérateur
Modosaurus Rex
Posté le 14-02-2001 à 12:04:48  profilanswer
 

Le coup du malloc inutile (un char) dans la creation, puis l'espoir que scanf allait mettre la chaine a cet emplacement avec ses petits bras muscles, ca c'est typique comme erreur de debutant.
On est tous passe par ce genre d'erreurs.
A+,


---------------
There's more than what can be linked! --  Le capitaine qui ne veut pas obéir à la carte finira par obéir aux récifs. -- Il ne faut plus dire Sarkozy, mais Sarkozon -- (╯°□°)╯︵ ┻━┻
n°14267
Evadream -​jbd-
Posté le 14-02-2001 à 12:47:44  profilanswer
 

Un grand merci, je pars en vacances avec ma disquette de sources et je vais potasser tout ca la bas ! Encore merci de m'avoir accordé de votre temps.

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

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

  [C] Listes chainées

 

Sujets relatifs
liste chainees simple 
Plus de sujets relatifs à : [C] Listes chainées


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)