Mon programme de liste chaînée s'arrête

Fermé
slim - Modifié le 16 mai 2022 à 12:21
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 16 mai 2022 à 16:33
bojour tout le monde
je trouve un probleme lors de l'execution de mon programme .
en effet lorsque j'execute et j'entre l'un des choix le programme ne me donne pas la resultat direct de plus il sort directement de la boucle apres avoir executer un choix .
 #include <stdio.h>
#include <stdlib.h>
typedef struct
{
    char nom[20],prenom[20];
    int rdv;
}patient;
struct cell
{
    patient p;
    struct cell* suivant ;
};
typedef struct cell* liste;
int choix()
{
    int ch;
    printf("---Voici les choix------------------------------------\n");
    printf("--0--Quitter------------------------------------------\n");
    printf("--1--afficher patient ---------------------\n");
    printf("--2--ajouter patient ------\n");
    printf("--3--rendez vous------------------------\n");
    printf("--4--supprimer patient -\n");
    printf("--5--consulter salle d'attente ----------------\n");
    printf("--6--sauvegarder patient --------\n");
    printf("--7--recuperer liste patient  --------\n");
    do
    {
        printf("donner votre choix=");
        scanf("%d",&ch);
        system("cls");
    }
    while(ch<0||ch>10);
    return ch;
}
void saisirPatient(patient *p)
{
    printf("nom=");scanf("%s",p->nom);
    printf("prenom=");scanf("%s",p->prenom);
    printf("rdv=");scanf("%d",p->rdv);
}
void afficherPatient(patient p)
{
    printf("nom=%s",p.nom);
    printf("prenom=%s",p.prenom);
    printf("rdv=%d",p.rdv);
}
liste ajouterPatient(liste tete,patient p)
{
    liste nouv,tete1=tete;
    nouv=(patient *)malloc(sizeof(patient));
    nouv->suivant=NULL;
    while(tete->suivant!=NULL)
    {
        tete1=tete1->suivant;
    }
    tete1->suivant=nouv;
    return tete;
}
void rendezVous(liste tete,int *rdv,int *srdv)
{
    liste tete1=tete;
    while(tete1!=NULL)
    {
     if (tete->p.rdv==0)
     {
         (*rdv)++;
     }
     else
     {
         (*srdv)++;
     }
     tete1=tete1->suivant;
    }
    printf("les rendez vous en ete compte");
}
liste supprimerPatient(liste tete)
{
 liste tete1=tete,p,pred=NULL;
 int rdv,srdv;
 rendezVous(tete,&rdv,&srdv);
 if (rdv==0)
 {
     p=tete1;
     tete1=tete1->suivant;
     free(p);
     return (tete);
 }
 else
 {
     while((tete1!=NULL && tete1->p.rdv==0))
     {
         pred=tete1;
         tete1=tete1->suivant;
     }
     if(tete1==NULL)
     {
         printf("erreur check");
     }
     else if (tete1==tete)
     {
     p=tete1;
     tete1=tete1->suivant;
     free(p);
     return(tete);
     }
     else
     {
         pred->suivant=tete1->suivant;
         p=tete;
         free(p);
         return tete;
     }
 }
}
void ConsulterSalleAttente(liste tete)
{
    liste tete1=tete,tete2=tete;
    while(tete1!=NULL)
    {
        if (tete1->p.rdv==1)
        {
            afficherPatient(tete1->p);
        }
        tete1=tete1->suivant;
    }
    while(tete2!=NULL)
    {
        if(tete2->p.rdv==0)
        {
            afficherPatient(tete2->p);
        }
        tete2=tete2->suivant;
    }
}
void sauvegarderPatient(liste tete,char *chemin)
{
    FILE* f=fopen((*chemin),"a");
    liste tete1=tete;
    if (f==NULL)
    {
        printf("erreur");
    }
    else
    {
     while(tete1!=NULL)
    {
        fprintf(f,"%s %s %d",tete1->p.nom,tete1->p.prenom,tete1->p.rdv);
        tete1=tete1->suivant;
    }
    }
    fclose(f);
}
liste recupererListePatient(liste tete,char *chemin)
{
    FILE* f=fopen((*chemin),"r");
    patient p;
    while(feof(f)!=0)
    {
        fscanf(f,"%s %s %d",p.nom,p.prenom,p.rdv);
        tete->p=p;
        tete=tete->suivant;
    }
    fclose(f);
    return tete;
}
int main()
{
    int ch;
    patient p;
    liste tete,tete1=tete;
    int rdv=0,srdv=0;
    char fich[20];
 ch=choix();
 do
 {
  switch(ch)
  {
     case 1:
     if (tete==NULL)
     {
         printf("pas de liste existante\n");
     }
     else
     {while(tete1!=NULL)
     {
         afficherPatient(tete1->p);
         tete1=tete1->suivant;
     }
     }
     ch=choix();
    break;
     case 2:
     saisirPatient(&p);
     tete=ajouterPatient(tete,p);
     ch=choix();
     break;
     case 3:
     rendezVous(tete,&rdv,&srdv);
     ch=choix();
     break;
     case 4:
     tete=supprimerPatient(tete);
     ch=choix();
     break;
     case 5:
     ConsulterSalleAttente(tete);
     ch=choix();
     break;
     case 6:
     printf("donner le nom du fichier =");
     scanf("%s",&fich);
     sauvegarderPatient(tete,&fich);
     ch=choix();
     break;
     case 7:
     printf("donner le nom du fichier a recuperer");
     scanf("%s",&fich);
     tete=recupererListePatient(tete,&fich);
     ch=choix();
     break;
  }
 }
 while(ch!=0);
 return 0;
}


***** Pour une lecture plus facile du code, à l'avenir utilisez les balises, VOIR CETTE PAGE
A voir également:

1 réponse

[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 094
Modifié le 16 mai 2022 à 12:51
Salut slim,

Tu n'avais pas posté ton code avec les balises de code du forum. A l'avenir fait le pour éviter du travail à la modération, qui a gentiment corrigé ton post.

Pour tes question :

Si tu veux répéter l'affichage du menu et la demande de saisie d'un chiffre tant que 0 n'est pas tapé, il faut que tu mettes ta boucle actuelle (l'appel à ta fonction
choix()
et le code qui traite le choix) dans une autre qui boucle tant que cette condition n'est pas avérée.

En ce qui concerne ton autre question : "lorsque j'execute et j'entre l'un des choix le programme ne me donne pas la resultat direct", elle est incompréhensible pour moi. Sois précis, dis exactement ce que tu fais, le comportement exact de ton programme et ce qu'il devrait faire à la place selon toi.

Sinon, ton programme comporte de nombreux bogues à en juger par les avertissements qui s'affichent en compilant avec les avertissements (et qui peuvent gérer des crashs ou des comportement inattendus) :

$ gcc -Wall -Wextra 37595064.c
37595064.c: In function ‘saisirPatient’:
37595064.c:39:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
printf("rdv=");scanf("%d",p->rdv);
~^ ~~~~~~
37595064.c: In function ‘ajouterPatient’:
37595064.c:50:6: warning: assignment to ‘liste’ {aka ‘struct cell *’} from incompatible pointer type ‘patient *’ {aka ‘struct <anonymous> *’} [-Wincompatible-pointer-types]
nouv=(patient *)malloc(sizeof(patient));
^
37595064.c:47:41: warning: unused parameter ‘p’ [-Wunused-parameter]
liste ajouterPatient(liste tete,patient p)
~~~~~~~~^
37595064.c: In function ‘sauvegarderPatient’:
37595064.c:137:17: warning: passing argument 1 of ‘fopen’ makes pointer from integer without a cast [-Wint-conversion]
FILE* f=fopen((*chemin),"a");
~^~~~~~~~
In file included from 37595064.c:1:
/usr/include/stdio.h:246:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern FILE *fopen (const char *__restrict __filename,
^~~~~
37595064.c: In function ‘recupererListePatient’:
37595064.c:155:17: warning: passing argument 1 of ‘fopen’ makes pointer from integer without a cast [-Wint-conversion]
FILE* f=fopen((*chemin),"r");
~^~~~~~~~
In file included from 37595064.c:1:
/usr/include/stdio.h:246:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern FILE *fopen (const char *__restrict __filename,
^~~~~
37595064.c:159:20: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
fscanf(f,"%s %s %d",p.nom,p.prenom,p.rdv);
~^ ~~~~~
37595064.c: In function ‘main’:
37595064.c:211:13: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat=]
scanf("%s",&fich);
~^ ~~~~~
37595064.c:212:29: warning: passing argument 2 of ‘sauvegarderPatient’ from incompatible pointer type [-Wincompatible-pointer-types]
sauvegarderPatient(tete,&fich);
^~~~~
37595064.c:135:42: note: expected ‘char *’ but argument is of type ‘char (*)[20]’
void sauvegarderPatient(liste tete,char *chemin)
~~~~~~^~~~~~
37595064.c:217:13: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat=]
scanf("%s",&fich);
~^ ~~~~~
37595064.c:218:37: warning: passing argument 2 of ‘recupererListePatient’ from incompatible pointer type [-Wincompatible-pointer-types]
tete=recupererListePatient(tete,&fich);
^~~~~
37595064.c:153:46: note: expected ‘char *’ but argument is of type ‘char (*)[20]’
liste recupererListePatient(liste tete,char *chemin)
~~~~~~^~~~~~
37595064.c: In function ‘supprimerPatient’:
37595064.c:114:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
37595064.c: In function ‘main’:
37595064.c:170:13: warning: ‘tete’ is used uninitialized in this function [-Wuninitialized]
liste tete,tete1=tete;
^~~~~


Ce n'est pas parce que ton programme n'a pas d'erreurs de syntaxe bloquant la génération d'un exécutable que tu dois ignorer les avertissements qui attirent ton attention sur des problèmes ou des choses que tu as écrites et qui n'ont pas de sens et qui dans 90% des cas sont des bogues.

Commence par le 1er avertissement, comprends le, corrige ton code, et recompile avec les avertissements. Attaque toi ensuite au suivant (toujours le 1er de la liste), corrige le, recompile, etc. Jusqu'à ce que ton code compile proprement.

Là le premier est :

37595064.c: In function ‘saisirPatient’:
37595064.c:39:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
printf("rdv=");scanf("%d",p->rdv);
~^ ~~~~~~


Comprends-tu pourquoi il t'est signalé ?

A l'avenir, rappelle toi que tu ne dois pas attendre d'avoir écrit plus de 200 lignes de code pour d'occuper des avertissements. Compile toujours avec les avertissements et travaille en cycles courts :
  • dès que tu as écrit quelques lignes, compile et vérifie l'absence d'erreurs et d'avertissements
  • dès que tu as écrit quelques lignes dont tu peux tester le comportement, exécute ton programme et vérifie ce comportement


ou mieux, écrit un test automatisé avant même d'avoir implémenté le comportement, et lance tous tes tests automatisés systématiquement sur ton code, à chaque modification subséquente, pour vérifier l'absence de régression sur ton code.

Dal
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 094
16 mai 2022 à 16:33
Si tu veux répéter l'affichage du menu et la demande de saisie d'un chiffre tant que 0 n'est pas tapé, il faut que tu mettes ta boucle actuelle (l'appel à ta fonction
choix()
et le code qui traite le choix) dans une autre qui boucle tant que cette condition n'est pas avérée.


par exemple, déplace ta ligne 173 à l'intérieur de la boucle
do
/
while
, en ligne 176 et retire tous les autres appels que tu fais à cette fonction.

Après chaque appel à
scanf()
, vide le buffer de stdin pour le purger du retour à la ligne et de ce qui a pu être tapé et qui n'a pas été consommé par
scanf()
. La façon standard de le faire en C est comme ceci :

                int c;
                while((c = getchar()) != '\n' && c != EOF)
                        /* discard */ ;


Tu peux mettre ceci dans une fonction, tel quel, et appeler ta fonction
empty_stdin();
ou comme tu veux.

Si ton programme s'arrête, c'est qu'il plante, et s'il plante, c'est, notamment en raison des nombreux problèmes signalés par les Warnings émis par le compilateur qui te signalent tes erreurs.

Si tu ne comprends pas ces messages d'avertissement, après avoir vu ton cours, manuel ou documentation, pose la question ici :-)
0