Liste chainée
Fermé
silver53
-
28 févr. 2008 à 16:48
SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 - 3 mars 2008 à 10:32
SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 - 3 mars 2008 à 10:32
A voir également:
- Liste chainée
- Liste déroulante excel - Guide
- Liste déroulante en cascade - Guide
- Liste groupe whatsapp - Guide
- Liste site streaming illégal - Accueil - Services en ligne
- Liste de diffusion whatsapp - Guide
7 réponses
oui, mais je dois récupérer le numéro dans un fichier, et j'ai vu que si je fais un fscanf(fichier, "%s %s %d %s", ...) et bien il ne me prend pas le 0 de mes numéros de telephonne.
Sinon une question : je devrais tirer les infos de mon fichier et les mettre dans un tableau de structure non? avant d'enclencher le processus de liste chainée?
Sinon une question : je devrais tirer les infos de mon fichier et les mettre dans un tableau de structure non? avant d'enclencher le processus de liste chainée?
SebManfred
Messages postés
484
Date d'inscription
mardi 28 août 2007
Statut
Membre
Dernière intervention
20 mai 2011
128
28 févr. 2008 à 17:00
28 févr. 2008 à 17:00
Salut,
tu m'as l'air de partir dans la bonne direction, mais tu n'es pas forcé de faire 2 fonctions différentes pour ajouter le 1er maillon et les autres. il te suffit juste de tester si ta tête est nulle, si oui tu insère le nouvel élément à partir de la tête, sinon tu rentre dans ta boucle qui teste si courant->suivant est nul
ah... juste une petite erreur : numero est un tableau de int... avec un strcpy tu n'iras pas loin...
tu m'as l'air de partir dans la bonne direction, mais tu n'es pas forcé de faire 2 fonctions différentes pour ajouter le 1er maillon et les autres. il te suffit juste de tester si ta tête est nulle, si oui tu insère le nouvel élément à partir de la tête, sinon tu rentre dans ta boucle qui teste si courant->suivant est nul
ah... juste une petite erreur : numero est un tableau de int... avec un strcpy tu n'iras pas loin...
#include stdafx.h
typedef struct contact_liste { // on définit la structure qui contiendra les infos du contact
char nom[30];
char prenom[30];
int numero[30];
char email[30];
struct contact_liste *suivant;
}contact;
typedef struct Liste_Repere { // on définit la structure pour avoir le contrôle sur la liste chainée contact_liste. On indique le premier élément, le dernier élément et le nombre d'éléments.
contact *debut;
contact *fin;
int taille;
}Liste;
void initialisation (Liste *liste){ // on initialise la liste chainée. liste est un pointeur de type Liste
liste->debut = NULL;
liste->fin = NULL;
taille = 0;
}
int insertion_dans_liste_vide (Liste * liste, char *NOM, char *PRENOM, int *NUMERO, char *EMAIL){
contact *nouveau_contact;
if ((nouveau_contact = (contact *) malloc (sizeof(contact)) == NULL)
{
printf("Erreur d'allocation mémoire");
return -1;
}
else
{
strcpy (nouveau_contact->nom, NOM);
strcpy (nouveau_contact->prenom, PRENOM);
nouveau_contact->numero=NUMERO;
strcpy (nouveau_contact->email, EMAIL);
nouveau_contact->suivant = NULL;
liste->debut = nouveau_contact;
liste->fin = nouveau_contact;
liste->taille++;
return 0;
}
}
int insertion_fin_liste (Liste * liste, contact * courant, char *NOM, char *PRENOM, int *NUMERO, char *EMAIL){
contact *nouveau_contact;
if ((nouveau_contact = (contact *) malloc (sizeof (contact))) == NULL)
{
printf("Erreur d'allocation mémoire");
return -1;
}
else
{
strcpy (nouveau_contact->nom, NOM);
strcpy (nouveau_contact->prenom, PRENOM);
nouveau_contact->numero=NUMERO;
strcpy (nouveau_contact->email, EMAIL);
courant->suivant = nouveau_element;
nouveau_contact->suivant = NULL;
liste->fin = nouveau_contact;
liste->taille++;
return 0;
}
void affichage (Liste * liste){
contact *courant;
courant = liste->debut;
while (courant != NULL){
printf ("%p - %s %s %d %s\n", courant, courant->nom, courant->prenom, courant->numero, courant->email);
courant = courant->suivant;
}
}
J'ai donc fais une nouvelle fonction pour insérer un nouveau maillon à la suite de ma liste, et une fonction pour afficher ma liste. Signalez moi les erreurs ^^
Il va me falloir maintenant une fonction pour trier les contacts, pour celà je pensais utiliser un maillon "tampon" où je stockerai le contact mal rangé, je supprimerai ce contact, accrocherai le suivant à la place, et ensuite je mettrai le tampon a la suite. (c'est pas très clair, un schéma serait plus simple)
Mais d'abord, j'aimerais un coup de pouce pour passer les données du fichier à la liste chainée.
typedef struct contact_liste { // on définit la structure qui contiendra les infos du contact
char nom[30];
char prenom[30];
int numero[30];
char email[30];
struct contact_liste *suivant;
}contact;
typedef struct Liste_Repere { // on définit la structure pour avoir le contrôle sur la liste chainée contact_liste. On indique le premier élément, le dernier élément et le nombre d'éléments.
contact *debut;
contact *fin;
int taille;
}Liste;
void initialisation (Liste *liste){ // on initialise la liste chainée. liste est un pointeur de type Liste
liste->debut = NULL;
liste->fin = NULL;
taille = 0;
}
int insertion_dans_liste_vide (Liste * liste, char *NOM, char *PRENOM, int *NUMERO, char *EMAIL){
contact *nouveau_contact;
if ((nouveau_contact = (contact *) malloc (sizeof(contact)) == NULL)
{
printf("Erreur d'allocation mémoire");
return -1;
}
else
{
strcpy (nouveau_contact->nom, NOM);
strcpy (nouveau_contact->prenom, PRENOM);
nouveau_contact->numero=NUMERO;
strcpy (nouveau_contact->email, EMAIL);
nouveau_contact->suivant = NULL;
liste->debut = nouveau_contact;
liste->fin = nouveau_contact;
liste->taille++;
return 0;
}
}
int insertion_fin_liste (Liste * liste, contact * courant, char *NOM, char *PRENOM, int *NUMERO, char *EMAIL){
contact *nouveau_contact;
if ((nouveau_contact = (contact *) malloc (sizeof (contact))) == NULL)
{
printf("Erreur d'allocation mémoire");
return -1;
}
else
{
strcpy (nouveau_contact->nom, NOM);
strcpy (nouveau_contact->prenom, PRENOM);
nouveau_contact->numero=NUMERO;
strcpy (nouveau_contact->email, EMAIL);
courant->suivant = nouveau_element;
nouveau_contact->suivant = NULL;
liste->fin = nouveau_contact;
liste->taille++;
return 0;
}
void affichage (Liste * liste){
contact *courant;
courant = liste->debut;
while (courant != NULL){
printf ("%p - %s %s %d %s\n", courant, courant->nom, courant->prenom, courant->numero, courant->email);
courant = courant->suivant;
}
}
J'ai donc fais une nouvelle fonction pour insérer un nouveau maillon à la suite de ma liste, et une fonction pour afficher ma liste. Signalez moi les erreurs ^^
Il va me falloir maintenant une fonction pour trier les contacts, pour celà je pensais utiliser un maillon "tampon" où je stockerai le contact mal rangé, je supprimerai ce contact, accrocherai le suivant à la place, et ensuite je mettrai le tampon a la suite. (c'est pas très clair, un schéma serait plus simple)
Mais d'abord, j'aimerais un coup de pouce pour passer les données du fichier à la liste chainée.
SebManfred
Messages postés
484
Date d'inscription
mardi 28 août 2007
Statut
Membre
Dernière intervention
20 mai 2011
128
29 févr. 2008 à 10:18
29 févr. 2008 à 10:18
attention, nouveau_contact->numero=NUMERO; ... il faut attribuer élément du tableau par élément du tableau
for(int i=0; i<30;i++)
{
nouveau_contact->numero[i] = numero[i];
}
pour le reste, quand tu reçois un nouvel élément, tu le mets automatiquement à la fin ou tu les classes dans l'ordre alphabétique?
si tu veux les classer, il te vaut une fonction de tri (tu en as déjà parlé), permettant de dire si un individu A est avant ou après un individu B et une fonction te permettant d'insérer un maillon à un emplacement précis de ta chaine.
en gros, tu testes quel est le dernier contact qui se situe "avant" ton nouveau contact (que ça soit dans l'ordre alphabétique ou un autre ordre... c'est toi qui choisis), et tu insère ton nouveau contact juste après ce dernier contact.
sinon, pour ce qui est de tout stocker dans un tableau, je ne pense pas que ça soit une bonne idée. le gros avantage de la liste chainée sur le tableau, c'est que tu ne précise pas la taille. quand tu lis ton fichier, à priori, je ne pense pas que tu saches combien d'enregistrement il contient...
le mieux, au niveau de la gestion de la mémoire, est d'enregistrer tes contacts au fur et à mesure que tu les lis.
et pour débusquer les erreurs, ce qui va t'apprendre le plus de choses, c'est de compiler et d'exécuter pour voir comment ça se comporte. tu peux mettre des printf pour tracer ce que fait ton programme, si tu veux, mais si je t'explique moi ce qui ne va pas, ça te sera beaucoup moins profitable que si tu te prend la tête et que tu trouve tout par toi-même.
si tu bloques, je te donnerai un coup de main, mais essaie d'abord par toi même
mais ton programme m'a l'air d'être bien parti.
for(int i=0; i<30;i++)
{
nouveau_contact->numero[i] = numero[i];
}
pour le reste, quand tu reçois un nouvel élément, tu le mets automatiquement à la fin ou tu les classes dans l'ordre alphabétique?
si tu veux les classer, il te vaut une fonction de tri (tu en as déjà parlé), permettant de dire si un individu A est avant ou après un individu B et une fonction te permettant d'insérer un maillon à un emplacement précis de ta chaine.
en gros, tu testes quel est le dernier contact qui se situe "avant" ton nouveau contact (que ça soit dans l'ordre alphabétique ou un autre ordre... c'est toi qui choisis), et tu insère ton nouveau contact juste après ce dernier contact.
sinon, pour ce qui est de tout stocker dans un tableau, je ne pense pas que ça soit une bonne idée. le gros avantage de la liste chainée sur le tableau, c'est que tu ne précise pas la taille. quand tu lis ton fichier, à priori, je ne pense pas que tu saches combien d'enregistrement il contient...
le mieux, au niveau de la gestion de la mémoire, est d'enregistrer tes contacts au fur et à mesure que tu les lis.
et pour débusquer les erreurs, ce qui va t'apprendre le plus de choses, c'est de compiler et d'exécuter pour voir comment ça se comporte. tu peux mettre des printf pour tracer ce que fait ton programme, si tu veux, mais si je t'explique moi ce qui ne va pas, ça te sera beaucoup moins profitable que si tu te prend la tête et que tu trouve tout par toi-même.
si tu bloques, je te donnerai un coup de main, mais essaie d'abord par toi même
mais ton programme m'a l'air d'être bien parti.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionsinon, pour ce qui est de tout stocker dans un tableau, je ne pense pas que ça soit une bonne idée. le gros avantage de la liste chainée sur le tableau, c'est que tu ne précise pas la taille. quand tu lis ton fichier, à priori, je ne pense pas que tu saches combien d'enregistrement il contient... le mieux, au niveau de la gestion de la mémoire, est d'enregistrer tes contacts au fur et à mesure que tu les lis.
En fait là où je bloque, c'est pour récupérer les données du fichier et les passer dans la liste chainée. Je pensais faire un fgets et tout stocker dans des tableaux intermédiaires, mais comme tu le dis, ce n'est pas la meilleure solution.
void récupérer_contact(contact *contact1)
#define TAILLE_MAX 30
int carlu;
contact lesContacts[TAILLE_MAX];
int i=0;
FILE* fichier=NULL;
fichier=fopen("contact.txt","r"); // on ouvre le fichier contact.txt
if(!fichier)
printf("erreur"); // lorsque l'ouverture du fichier echoue
else
{
do
{
for (i=0; i<=1000; i++)
{
carlu=fscanf(fichier, "%s %s %s %s", lesContacts[i].nom, lesContacts[i].prenom, lesContacts[i].numéro, lesContacts[i].email);// on rentre les données dans la structure
}
}
while(carlu!=EOF)
}
fclose(fichier);
Ici j'ai supposé qu'il n'y avait pas plus de 1000 contacts dans le fichiers.
Je pense qu'il doit y avoir une solution pour utiliser mes fonctions réalisées précédement afin de rentrer les données directement dans un maillon de la liste.
sinon, pour ce qui est de tout stocker dans un tableau, je ne pense pas que ça soit une bonne idée. le gros avantage de la liste chainée sur le tableau, c'est que tu ne précise pas la taille. quand tu lis ton fichier, à priori, je ne pense pas que tu saches combien d'enregistrement il contient...
le mieux, au niveau de la gestion de la mémoire, est d'enregistrer tes contacts au fur et à mesure que tu les lis.
En fait là où je bloque, c'est pour récupérer les données du fichier et les passer dans la liste chainée. Je pensais faire un fgets et tout stocker dans des tableaux intermédiaires, mais comme tu le dis, ce n'est pas la meilleure solution.
void récupérer_contact(contact *contact1)
#define TAILLE_MAX 30
int carlu;
contact lesContacts[TAILLE_MAX];
int i=0;
FILE* fichier=NULL;
fichier=fopen("contact.txt","r"); // on ouvre le fichier contact.txt
if(!fichier)
printf("erreur"); // lorsque l'ouverture du fichier echoue
else
{
do
{
for (i=0; i<=1000; i++)
{
carlu=fscanf(fichier, "%s %s %s %s", lesContacts[i].nom, lesContacts[i].prenom, lesContacts[i].numéro, lesContacts[i].email);// on rentre les données dans la structure
}
}
while(carlu!=EOF)
}
fclose(fichier);
Ici j'ai supposé qu'il n'y avait pas plus de 1000 contacts dans le fichiers.
Je pense qu'il doit y avoir une solution pour utiliser mes fonctions réalisées précédement afin de rentrer les données directement dans un maillon de la liste.
le mieux, au niveau de la gestion de la mémoire, est d'enregistrer tes contacts au fur et à mesure que tu les lis.
En fait là où je bloque, c'est pour récupérer les données du fichier et les passer dans la liste chainée. Je pensais faire un fgets et tout stocker dans des tableaux intermédiaires, mais comme tu le dis, ce n'est pas la meilleure solution.
void récupérer_contact(contact *contact1)
#define TAILLE_MAX 30
int carlu;
contact lesContacts[TAILLE_MAX];
int i=0;
FILE* fichier=NULL;
fichier=fopen("contact.txt","r"); // on ouvre le fichier contact.txt
if(!fichier)
printf("erreur"); // lorsque l'ouverture du fichier echoue
else
{
do
{
for (i=0; i<=1000; i++)
{
carlu=fscanf(fichier, "%s %s %s %s", lesContacts[i].nom, lesContacts[i].prenom, lesContacts[i].numéro, lesContacts[i].email);// on rentre les données dans la structure
}
}
while(carlu!=EOF)
}
fclose(fichier);
Ici j'ai supposé qu'il n'y avait pas plus de 1000 contacts dans le fichiers.
Je pense qu'il doit y avoir une solution pour utiliser mes fonctions réalisées précédement afin de rentrer les données directement dans un maillon de la liste.
Finalement :
void load(Contact **Tete){
FILE *contact = NULL;
Contact *Tete;
char NOM[TAILLE_MAX] = "";
char PRENOM[TAILLE_MAX] = "";
char NUMERO[TAILLE_MAX] = "";
char EMAIL[TAILLE_MAX] = "";
*Tete = NULL;
system("cls");
contact = fopen("contact.txt", "r");
if (contact != NULL){
while (fscanf(contact, "%s %s %s %s", NOM, PRENOM, NUMERO, EMAIL ) != NULL){
Contact *Nouveau = (Contact*)malloc(sizeof(Contact));
sprintf(Nouveau->nom, "%s",NOM);
sprintf(Nouveau->prenom, "%s",PRENOM);
sprintf(Nouveau->numero, "%s",NUMERO);
sprintf(Nouveau->email, "%s",EMAIL);
Nouveau->suivant = (*Tete);
(*Tete) = Nouveau;
}
}
fclose(contact);
system("pause");
}
maintenant j'aimerais trier cette liste chainée, voilà ce que j'ai fait :
void tri(Contact *tete)
{
Contact actuel = *tete;
Contact precedent = actuel->suivant;
Contact tmp = NULL;
printf("actuel : %d\n",actuel-> valeur);
printf("precedent : %d\n",precedent-> valeur);
while(precedent != NULL)
{
if (strcmp(actuel->nom, precedent->nom)>1)
{
tmp = precedent
precedent = actuel;
actuel = tmp ;
}
actuel=actuel->suivant;
}
aidez moi à m'en sortir
void load(Contact **Tete){
FILE *contact = NULL;
Contact *Tete;
char NOM[TAILLE_MAX] = "";
char PRENOM[TAILLE_MAX] = "";
char NUMERO[TAILLE_MAX] = "";
char EMAIL[TAILLE_MAX] = "";
*Tete = NULL;
system("cls");
contact = fopen("contact.txt", "r");
if (contact != NULL){
while (fscanf(contact, "%s %s %s %s", NOM, PRENOM, NUMERO, EMAIL ) != NULL){
Contact *Nouveau = (Contact*)malloc(sizeof(Contact));
sprintf(Nouveau->nom, "%s",NOM);
sprintf(Nouveau->prenom, "%s",PRENOM);
sprintf(Nouveau->numero, "%s",NUMERO);
sprintf(Nouveau->email, "%s",EMAIL);
Nouveau->suivant = (*Tete);
(*Tete) = Nouveau;
}
}
fclose(contact);
system("pause");
}
maintenant j'aimerais trier cette liste chainée, voilà ce que j'ai fait :
void tri(Contact *tete)
{
Contact actuel = *tete;
Contact precedent = actuel->suivant;
Contact tmp = NULL;
printf("actuel : %d\n",actuel-> valeur);
printf("precedent : %d\n",precedent-> valeur);
while(precedent != NULL)
{
if (strcmp(actuel->nom, precedent->nom)>1)
{
tmp = precedent
precedent = actuel;
actuel = tmp ;
}
actuel=actuel->suivant;
}
aidez moi à m'en sortir
SebManfred
Messages postés
484
Date d'inscription
mardi 28 août 2007
Statut
Membre
Dernière intervention
20 mai 2011
128
3 mars 2008 à 10:32
3 mars 2008 à 10:32
je ne comprend pas très bien pourquoi tu fais comme ça, notamment le "precedent = actuel->suivant;"...
tu peux trier à l'enregistrement : tu as 5 noms : AAAA, DDDD, FFFF, JJJJ et MMMM, tu veux insérer le nom EEEE
tu teste à partir de la tête de ta liste, tant que le nom courant est inférieur au nouveau nom, tu passe au nom suivant, puis des que le nom courant est supérieur au nouveau nom, tu insère le nouveau nom entre le nom précédent et le nom courant, et ta liste sera triée dès sa création
après, si tu veux faire une fonction qui te trie une liste déjà existante, ça peut dépendre beaucoup de comment tu veux la trier : des algorithmes de tri, il en existe beaucoup, tout dépend de ce que tu veux en faire.
tu peux trier à l'enregistrement : tu as 5 noms : AAAA, DDDD, FFFF, JJJJ et MMMM, tu veux insérer le nom EEEE
tu teste à partir de la tête de ta liste, tant que le nom courant est inférieur au nouveau nom, tu passe au nom suivant, puis des que le nom courant est supérieur au nouveau nom, tu insère le nouveau nom entre le nom précédent et le nom courant, et ta liste sera triée dès sa création
après, si tu veux faire une fonction qui te trie une liste déjà existante, ça peut dépendre beaucoup de comment tu veux la trier : des algorithmes de tri, il en existe beaucoup, tout dépend de ce que tu veux en faire.