[C] Liste chainée problème pointeurs

Résolu/Fermé
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 - 6 mai 2008 à 21:42
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 - 7 mai 2008 à 20:57
Bonjsoir,

j'ai des problèmes pour venir insérer un jeton dans une liste chainée.
Je cherche a insérer le jeton nouveau selon ses données (date + heure, que j'ai nommé horloge).

Voici la fonction :

void InsertionDuMessage(Message **listeSMS,char *SMS,char *date, char *horloge)
{
int sortie=0;
Message *nouveau=(Message*)malloc(sizeof(Message));
strcpy(nouveau->SMS,SMS);
strcpy(nouveau->date,date);
strcpy(nouveau->horloge,horloge);
nouveau->suivant=NULL;
if((*listeSMS)!=NULL)// si y'a deja des messages chainés
{

while(sortie==0)//tant qu'on est pas au bout
{
if(strcmp((*listeSMS)->date,nouveau->date)<0)// si la date de la liste chainée est anterieur au nouveau
{
printf("baca");
*listeSMS=(*listeSMS)->suivant;
printf("oui, la date est antérieur\n");// on passe au suivant
}
else// sinon la date est antérieur ou égale
{
printf("bggg");
printf("sinon car on a bien %s <= %s\n",(*listeSMS)->date,nouveau->date);
if(strcmp((*listeSMS)->date,nouveau->date)==0 && strcmp((*listeSMS)->horloge,nouveau->horloge)<0)// si l'horloge de la liste chainée est antéireur au nouveau
{
printf("et voilà %s < %s\n",(*listeSMS)->horloge,nouveau->horloge);_sleep(1000);
printf("%s",(*listeSMS)->suivant);
(*listeSMS)=(*listeSMS)->suivant;// on change de jeton
}
else
{
printf("bon alors\n");
nouveau->suivant=(*listeSMS);// une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
(*listeSMS)=nouveau;
sortie=1;
}
}
printf("presque");
if(*listeSMS==NULL)
{
nouveau->suivant=(*listeSMS);// une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
(*listeSMS)->suivant=nouveau->suivant;
sortie=1;printf("on arrete là\n");_sleep(3000);
}
}
}
else// sinon on a encore aucuns sms dans ce contact
{
nouveau->suivant=(*listeSMS);
(*listeSMS)=nouveau;
printf("on passe au 1er\n");
}
}


Je suis quasi certain que c'est des problèmes de pointeurs suivant que je ne met pas les bons, parfois quand je l'ai fait (comme c'est le cas içi, une fenetre windows me demande d'arreter) ou bien les autres fois je n'avait plus que le dernier jeton c'est a dire nouveau dans ma liste chainée.

Merci pour l'aide.
+

4 réponses

daronmaster Messages postés 326 Date d'inscription vendredi 12 janvier 2007 Statut Membre Dernière intervention 11 mai 2009 44
6 mai 2008 à 21:56
quand tu fais strcpy(nouveau->SMS,SMS), ne pense tu pas avoir un pb ?

ton pointeur nouveau->SMS qui est un char * n'a pas eu de zone mémoire allouée avant de faire la copie.

ceci je pense est un prmier pb

idem pour date et horloge

et un conseil prend un pointeur temporaire car tu balade listeSMS ce qui implique que lorsque tu fais des listeSMS=listeSMS->suivant tu perd de l'info

voici ce que j'aurai fait :

Message *tmp = *listeSMS;
if(strcmp(tmp->date,nouveau->date)<0)// si la date de la liste chainée est anterieur au nouveau
{
printf("baca");
if (tmp->suivant != NULL)
tmp=tmp->suivant;
printf("oui, la date est antérieur\n");// on passe au suivant
else{
tmp->suivant = nouveau;

sortie = 1;
}
}
else// sinon la date est antérieur ou égale
{
printf("bggg");
printf("sinon car on a bien %s <= %s\n",(*listeSMS)->date,nouveau->date);
if(strcmp(tmp->date,nouveau->date)==0 && strcmp(tmp->horloge,nouveau->horloge)<0)// si l'horloge de la liste chainée est antéireur au nouveau
{
printf("et voilà %s < %s\n",tmp->horloge,nouveau->horloge);_sleep(1000);
printf("%s",tmp->suivant);
if (tmp->suivant != NULL)
tmp=tmp->suivant;// on change de jeton
else
tmp->suivant = nouveau;

sortie = 1;
}
else
{
printf("bon alors\n");
nouveau->suivant=(*listeSMS);// une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
(*listeSMS)=nouveau;
sortie=1;
}
}
printf("presque");
if(*listeSMS==NULL)
{
nouveau->suivant=(*listeSMS);// une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
// ||| ERROR |||(*listeSMS)->suivant=nouveau->suivant; tu ne peut pas faire ca, ta liste == NULL

*liste=nouveau;
sortie=1;printf("on arrete là\n");_sleep(3000);
}
}
}
else// sinon on a encore aucuns sms dans ce contact
{
nouveau->suivant=(*listeSMS);
(*listeSMS)=nouveau;
printf("on passe au 1er\n");
}

voila essaie ça je ne te garantie rien mais bon

allez salut
0
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
6 mai 2008 à 22:29
salut daronmaster,
ton code a l'air de fonctionner, dcependant je n'arrive pas a ajouter + de 2 contacts dans la listes. Avant de faire appel a toi, je le les triait pas et je les inséraient en tete. ça marchait on pourvait en mettre + de 2.


void InsertionDuMessage(Message **listeSMS,char *SMS,char *date, char *horloge)
{
int sortie=0;
Message *nouveau=(Message*)malloc(sizeof(Message));
strcpy(nouveau->SMS,SMS);
strcpy(nouveau->date,date);
strcpy(nouveau->horloge,horloge);
nouveau->suivant=NULL;
if((*listeSMS)!=NULL)// si y'a deja des messages chainés
{

while(sortie==0)//tant qu'on est pas au bout
{
Message *tmp = *listeSMS;
if(strcmp(tmp->date,nouveau->date)<0)// si la date de la liste chainée est anterieur au nouveau
{
printf("baca");
if (tmp->suivant != NULL)
{
tmp=tmp->suivant;
printf("oui, la date est antérieur\n");}// on passe au suivant
else
{
tmp->suivant = nouveau;

sortie = 1;
}
}
else// sinon la date est antérieur ou égale
{
printf("bggg");
printf("sinon car on a bien %s <= %s\n",(*listeSMS)->date,nouveau->date);
if(strcmp(tmp->date,nouveau->date)==0 && strcmp(tmp->horloge,nouveau->horloge)<0)// si l'horloge de la liste chainée est antéireur au nouveau
{
printf("et voilà %s < %s\n",tmp->horloge,nouveau->horloge);_sleep(1000);
printf("%s",tmp->suivant);
if (tmp->suivant != NULL)
tmp=tmp->suivant;// on change de jeton
else
tmp->suivant = nouveau;

sortie = 1;
}
else
{
printf("bon alors\n");
nouveau->suivant=(*listeSMS);// une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
(*listeSMS)=nouveau;

sortie=1;
}
}
printf("presque");
if(*listeSMS==NULL)
{
nouveau->suivant=(*listeSMS);// une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
*listeSMS=nouveau;
sortie=1;printf("on arrete là\n");_sleep(3000);
}
}
}
else// sinon on a encore aucuns sms dans ce contact
{
nouveau->suivant=(*listeSMS);
(*listeSMS)=nouveau;
}
}

Donc j'vais essayer de voir ce qui cloche mais je pense qu'il s'agit des condition de sortie de la boucle.
++
0
daronmaster Messages postés 326 Date d'inscription vendredi 12 janvier 2007 Statut Membre Dernière intervention 11 mai 2009 44
7 mai 2008 à 15:32
quel est le format de la date? et de l'horloge ? car si c'est du type jj/mm/aaaa alors il faut faire attention et strcmp ne suffit pas --> strcmp("10/03/1999","12/02/1900") renvoie -1 alors que ce que tu voudrait est 1 (1999 > 1900)

je regarde le code et je te le remets nickel
0
daronmaster Messages postés 326 Date d'inscription vendredi 12 janvier 2007 Statut Membre Dernière intervention 11 mai 2009 44
7 mai 2008 à 15:46
je n'ai pas testé mais regarde ce qui suit, trajoute tes printf (je les ai enlevé pour plus de lisibilté)

pour ta structure remplace comme ceci :

typedef struct Message{
char *SMS;
char *date;
char *horloge;
struct Message *suivant;
}Message;


void InsertionDuMessage(Message **listeSMS,char *SMS,char *date, char *horloge) 
{
 
int sortie=0; 

Message *nouveau=(Message*)malloc(sizeof(Message));

/* allocation des champs de la structure*/
 
nouveau->SMS = (char *)malloc(sizeof(char)*(strlen(SMS)+1));

nouveau->date = (char *)malloc(sizeof(char)*(strlen(date)+1));

nouveau->horloge = (char *)malloc(sizeof(char)*(strlen(horloge)+1));

/*copie des elements*/

strcpy(nouveau->SMS,SMS); 

strcpy(nouveau->date,date); 

strcpy(nouveau->horloge,horloge);

 

nouveau->suivant=NULL;

/*variables temporaires*/

Message *tmp = *listeSMS;

Message *tmp2 = *tmp;



if(*liste == NULL)		/*cas de la liste vide*/
	*listeSMS = nouveau;
else

while(!sortie)//tant qu'on est pas au bout 
{  

	if(strcmp(tmp->date,nouveau->date)<0)// si la date de la liste chainée est anterieur au nouveau 
	{ 
		printf("baca"); 
		
		if (tmp->suivant != NULL) 
		{
			tmp2=tmp;
 
			tmp=tmp->suivant; 

		}else 
		{ 
			tmp->suivant = nouveau; 

			sortie = 1; 
		} 
	} 
	else// sinon la date est antérieur ou égale 
	{

		if(strcmp(tmp->date,nouveau->date)==0){ //on regarde l'horloge, forcement un decalage horaire entre 2 SMS
			
			if(strcmp(tmp->horloge,nouveau->horloge)<0){//on regarde le message suivant
				
				if(tmp->suivant != NULL){
					tmp2=tmp;

					tmp=tmp->suivant;					
				}
				else{
					tmp->suivant=nouveau;
	
					sortie = 1;
				}
			}else{
				nouveau->suivant = tmp;
			
				tmp2->suivant = nouveau;

				sortie = 1;
			}		
		}
		else{

			tmp2->suivant = nouveau;

			nouveau->suivant = tmp;

			sortie = 1;
		}
	}
}


bon courage en espérant que cela marche

tchu et bon week-end
0
daronmaster Messages postés 326 Date d'inscription vendredi 12 janvier 2007 Statut Membre Dernière intervention 11 mai 2009 44
7 mai 2008 à 15:56
j'allais oublié, pense àfaire des free par la suite sinon tu auras des fuites mémoires

du genre :

void mon_free(Message **listeSMS){

Message *tmp;

while(*listeSMS != NULL){

     tmp = *listeSMS;

    *listeSMS = *listeSMS->suivant;

     free(tmp->SMS);
     free(tmp->date);
     free(tmp->horloge);
     free(tmp);

}

}
0
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
7 mai 2008 à 20:57
salut daronmaster,
j'ai un peu travaillé cette nuit car je doit rendre mon projet d'info (je suis en 2ième année d'école d'ingé ESTACA) ce vendredi. J'ai changé la fonction, elle marche nickel. Bon j'ai aussi changé ma méthode de tri, mais pour ceux qui souhaiteront avoir la solution, je poste la mienne :

void InsertionDuMessage(Message **listeSMS,char *SMS,char *date, char *horloge)
{
int i=0,j=0,position=-1;

Message* nouveau=(Message*)malloc(sizeof(Message));
strcpy(nouveau->SMS,SMS);
strcpy(nouveau->date,date);
strcpy(nouveau->horloge,horloge);

if((*listeSMS)!=NULL)// si y'a deja des messages chainés
{
Message* pcourant=*listeSMS; // on cree deux pointeurs tous deux initialises sur la tete de pp_liste
Message* p_parcours=*listeSMS;
for(i=0;p_parcours!=NULL;i++)
{
if((strcmp(p_parcours->date,nouveau->date)<0) || (strcmp(p_parcours->date,nouveau->date)==0) && (strcmp(p_parcours->horloge,nouveau->horloge)<0)) //on "regarde" ou il faudra inserer le nouveau jeton (par exemple sur le 3 ieme parcouru etc)
position=i;
p_parcours=p_parcours->suivant; //pour cela nous devons parcourir la liste chainee
}
if (position>=0) // avec le if du desssus, on connais alors la position dans laquelle on doit realiser l'insertion
{
for(j=0;j<position;j++)
pcourant=pcourant->suivant; // on recherche la bonne place pour inserer le jeton
nouveau->suivant=pcourant->suivant; // une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
pcourant->suivant=nouveau;
}
else //sinon c'est deja trie
{
nouveau->suivant=*listeSMS;
*listeSMS=nouveau;
}
}
else
{
nouveau->suivant=(*listeSMS);
(*listeSMS)=nouveau;
}

}

voilà si des gens veulent tester mon projet sur l'utilisation des contacts, faites le moi savoir par mail :
jobert@estaca.fr

++
0