Bug introuvable, structs pointeurs

Résolu
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007 - 18 févr. 2007 à 23:11
cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008 - 20 févr. 2007 à 21:36
Je fais un programme en c++ et j'ai un bug assez bizarre je n,arrive pas à en trouver la cause.. j'aimerais bien que quelqu'un m'aide parce que ça fait plusieurs jours que je tourne en rond à essayer tout et n'importe quoi..

le programme consiste jusqu,a maintenant des structures avec pointeurs dans lequel rentre les données d'un fichier .txt  et lequel on affiche après avoir demandé quelque chose à l'usager.. en ce moment tout ce que ça fait c'Est entrer la premier parti des données , puis ça bloque rendu après un tour de la boucle principale , c'Est à dire après "1 professeur"(selon mon type de donnée) j'ai mis en commentaire un gros "bug ici après second tour" pour mettre en évidence l,emplacement exact ou ça bug..et c'est à la création d'une nouvelle case pour la struct et il me semble que ça devrait fonctionner..

voici le code à problème.. je le met en entier au cas où vous voudriez le voir "fonctionner"..merci

#include
#include <string.h>
#include <stdlib.h>
#include
#include <fstream.h>
const int nb_charac_max=80;
struct Cours
{
    char *sigle;
    Cours *suivant;
};



struct Etudiant
{
    char *nom;
    Etudiant *suivant;
};



struct Professeur
{
    char *nom;
    int experience;
    Cours *listecours;
    Etudiant *listetudiants;
    Professeur *suivant;
};





class DossierProfesseur
{
  
       
    public:
  Professeur *tete;
        DossierProfesseur(char *FP);
        ~DossierProfesseur();
  void affichage();

 
};



DossierProfesseur::DossierProfesseur(char *FP)
{
 char * t ;
 Professeur *profCourant=tete=new Professeur();
 cout<< "2";
 profCourant->suivant=new Professeur();
 cout<< "3";
 profCourant = profCourant->suivant; 
 
 ifstream lecture(FP,ios::nocreate);
 
 if(lecture.fail())         //condition si l'ouverture envoie une erreur
 {
  cout<<"Erreur a l'ouverture du fichier"<<endl; //message d'erreur
  exit(1);          //sortir du programme lors d'une erreur
 }
 



 while(!lecture.eof())        //boucle qui lit jusqu'à la fin du fichier
 {
  cout << "again " << endl;
  //******************************************
  //*********bug ici au second tour***********
  profCourant->nom = new char[25];     



  cout <<"5";
  lecture.getline(profCourant->nom, nb_charac_max);
  lecture>>profCourant->experience;
   
  cout << profCourant->experience << "**6";
  Cours *coursCourant=profCourant->listecours=new Cours();
  coursCourant->suivant=new Cours();
  coursCourant=coursCourant->suivant;
  Etudiant *etudiantCourant=profCourant->listetudiants=new Etudiant();
  etudiantCourant->suivant=new Etudiant();
  etudiantCourant=etudiantCourant->suivant;
  t = new char [10];         // A remplacer dynamiquement !
   
  while(t[0]!='&' && !lecture.eof())
  {
   lecture>> t ;
   coursCourant->sigle = new char [10];               
   strcpy (coursCourant->sigle,t);
   coursCourant->suivant=new Cours();
   coursCourant=coursCourant->suivant;
  
   
  }
  while(t[0]!='&' && !lecture.eof())
  {
   lecture>> t;
   etudiantCourant->nom = new char [20];               
   strcpy (etudiantCourant->nom,t);
   etudiantCourant->suivant=new Etudiant();
   etudiantCourant=etudiantCourant->suivant;
  
   
  }
  cout<< "1";
  coursCourant->suivant= NULL;
  cout<< "1 1/2";
  etudiantCourant->suivant= NULL;
  
  profCourant->suivant=new Professeur();
 
  cout<< "3";
  profCourant = profCourant->suivant; 
  
  cout<< "4";
  profCourant->suivant = NULL;
 }



 
 
}



void DossierProfesseur::affichage()
{
    Professeur *profCourant=tete;
    profCourant=profCourant->suivant;
    
    while(profCourant->suivant!=NULL)
    {
       
        cout << profCourant->nom      << endl;
        cout << profCourant->experience   << endl;
        cout << "------------------------------------------------" << endl;
        //liste des cours pour ce prof
        Cours *coursCourant=profCourant->listecours;
        while(coursCourant->suivant!=NULL)
        {
            coursCourant=coursCourant->suivant;
            cout << coursCourant->sigle << endl;
        }



        profCourant=profCourant->suivant;
    }
}



void  main()
{
   
 char option_menu[1];
 char text_option_menu[nb_charac_max];
 cout << "Quel action desirez vous effectuer? (- nom et prenom, *, % nom du cours, $ nom du fichier)";
 cin >> option_menu[0];
 cin.ignore(2, '[');
 cin.get(text_option_menu, nb_charac_max,']');





 switch(option_menu[0]){
 case '-':cout << "supprimer" << endl << text_option_menu << endl;break;
 case '*':cout << "nom plus demander";break;
 case '%':cout << "cours";break;
 case '$':cout << "sauvegarde";break;
 };



    DossierProfesseur *dossierProfesseur;
   
 dossierProfesseur= new DossierProfesseur("fp.txt");
  
    dossierProfesseur->affichage();



};

15 réponses

cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008
20 févr. 2007 à 20:43
salut voici la boucle qui posait problème, elle marche maintenant:

 while(!lecture.eof())        //boucle qui lit jusqu'à la fin du fichier
 {
  printf(" again \n");
  profCourant->nom = new char[25];    
 
  printf("5\n");
  lecture.getline(profCourant->nom, 25);
  printf("profCourant->nom= %s\n",profCourant->nom);
  lecture>>profCourant->experience;
 
  /********/
  printf("profCourant->experience= %d\n", profCourant->experience );
  printf("**6\n");
  /********/
  Cours *coursCourant=profCourant->listecours=new Cours();
  coursCourant->suivant=new Cours();
  coursCourant=coursCourant->suivant;
  Etudiant *etudiantCourant=profCourant->listetudiants=new Etudiant();
  etudiantCourant->suivant=new Etudiant();
  etudiantCourant=etudiantCourant->suivant;
  t = new char [10];

  while(!lecture.eof())
  {/*******/
    printf(" boucle1 \n");
    getchar();// pour executer pas à pas
    /*********/
   coursCourant->sigle = new char [10];
   lecture>> t ;
   if (t[0]=='&') break;
   printf("t= %s\n",t);
   strcpy (coursCourant->sigle,t);
   printf("coursCourant->sigle= %s\n",coursCourant->sigle);
   coursCourant->suivant=new Cours();
   coursCourant=coursCourant->suivant;
  }
 
  while(!lecture.eof())
  {/*******/
    printf(" boucle2 \n");
    getchar();//pour executer pas à pas
    /********/
   etudiantCourant->nom = new char [25];

    lecture>> t ;
    if (t[0]=='&') break;
    printf("t= %s\n",t);
   strcpy (etudiantCourant->nom,t);
   printf("etudiantCourant->nom= %s\n",etudiantCourant->nom);
   etudiantCourant->suivant=new Etudiant();
   etudiantCourant=etudiantCourant->suivant;
  }
 
  profCourant->suivant=new Professeur();
  profCourant = profCourant->suivant;
  profCourant->suivant = NULL;
  lecture>> t ;
 }
3
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
18 févr. 2007 à 23:14
ah et le fichier txt ressemble à ceci, merci encore

GAGNON PIERRE LUC
15
SIF100
SIF101
SIF104
SIF106
&
BOUDREAULT
COTE
VILLENEUVE
FLAMAND
DERY
&
BEAUDOIN GUILLAUME
20
SIF102
SIF103
SIF100
SIF104
&
DERY
FILLION
VERREAULT
FLAMAND
COTE
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
19 févr. 2007 à 16:50
Salut,
Je te conseille de faire un debug ligne par ligne avec point d'arret sur début du constructeur pour vérif de TOUTES les valeurs,
et aussi d'extraire les allocations dans une méthode dédiée pour plus de clarté lors de la destruction (que je ne vois pas ici)
0
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
19 févr. 2007 à 18:56
salut
j'ai fait le debug autant que possible.. j'ai pu vérifier que le bug semblait provenir de la ligne   profCourant->nom = new char[25];  au second tour de boucle..
aussi, je ne vois pas très bien pourquoi tu parles de destruction, le problème ne peut pas être à ce niveau il me semble..
merci pour ton intrêt à mon problème tout de même..
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
goast_tu Messages postés 212 Date d'inscription dimanche 3 avril 2005 Statut Membre Dernière intervention 28 mai 2011 2
20 févr. 2007 à 11:54
profCourant->nom = new char[25];     

  cout <<"5";
  lecture.getline(profCourant->nom, nb_charac_max);





je n'ai pas fais du C++
(que du C) mais d'apres ce que je comprend tu reserve de l'espace pour
25 caracters et ensuit tu essay de lire le nom de

nb_charac_max caracters(donc 80) c'est deja une erreur. Mais je pence pas que ca vien de la car aucun nom dans le fichier ne depasse pas 25 caracters










<hr size="2" width="100%" />



Trafic web gratuit!!!
0
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
20 févr. 2007 à 16:07
salut


bien vu, mais effectivement ce n'est pas le problème. j'ai corrigé, et ça ne change rien. merci d'essayer tout de même
0
cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008
20 févr. 2007 à 16:30
salut
essai printf à la place de cout dans le corps du constructeur DossierProfesseur::DossierProfesseur(char *FP) et tu sera vraiment surpris.
pour la 1° fois entré ds la boucle while(!lecture.eof())  : il ne rentre pas ds les 2 boucles
while(t[0]!='&' && !lecture.eof())
et pour la 2° fois il boucle à l'infini à l'interieur de  la 1° bouclewhile(t[0]!='&' &&!lecture.eof())
c'est bizzar mais je l'ai testé.
0
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
20 févr. 2007 à 16:54
la boucle a l'infini c'Est parce qu'il n'a plus de donné à  entrer dans la struct donc il ne tombe jamais sur le "&" du document texte..
pour ce qui est des 2 while de suite, c'Est vrai, c'Est un oublie de ma part, cependant ça ne cause pas d'autre problème que d'oublier une boucle, et c'est maintenant règlé.. et pour ce qui est des printf, je ne vois vraiment pas le lien, surtout que les cout sont juste la pour des tests façon de m'éviter de faire des debug à chaque fois.
0
cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008
20 févr. 2007 à 17:39
salut
envois ton programme avec les modifications que t'as faite. pour voir plus clair.
0
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
20 févr. 2007 à 18:08
#include
#include <string.h>
#include <stdlib.h>
#include
#include <fstream.h>
const int nb_charac_max=80;
struct Cours
{
    char *sigle;
    Cours *suivant;
};



struct Etudiant
{
    char *nom;
    Etudiant *suivant;
};



struct Professeur
{
    char *nom;
    int experience;
    Cours *listecours;
    Etudiant *listetudiants;
    Professeur *suivant;
};





class DossierProfesseur
{
  
       
    public:
  Professeur *tete;
        DossierProfesseur(char *FP);
        ~DossierProfesseur();
  void affichage();
        //void supprimer(char *nom);
        //void afficherLaListe() const;
        char *afficherLeProfSuperviseEtudiant(char *nom) const;
        //char *afficherProfexperienceDuCoursPlusDemande(char *coursdonne) const;
        //int afficherCoursLePlusDemande() const;
        //void recopier(char *FP);
};
/*DossierProfesseur::
{
 


}*/


DossierProfesseur::DossierProfesseur(char *FP)
{
 char * t ;
 Professeur *profCourant=tete=new Professeur();
 cout<< "2";
 profCourant->suivant=new Professeur();
 cout<< "3";
 profCourant = profCourant->suivant; 
 
 ifstream lecture(FP,ios::nocreate);
 
 if(lecture.fail())         //condition si l'ouverture envoie une erreur
 {
  cout<<"Erreur a l'ouverture du fichier"<<endl; //message d'erreur
  exit(1);          //sortir du programme lors d'une erreur
 }
 


 while(!lecture.eof())        //boucle qui lit jusqu'à la fin du fichier
 {
  //******************************************
  //*********bug ici au second tour***********
  
  profCourant->nom = new char[25];     
 
  cout <<"5";
  lecture.getline(profCourant->nom, 25);
  lecture>>profCourant->experience;   
  cout << profCourant->experience << "**6";
  Cours *coursCourant=profCourant->listecours=new Cours();
  coursCourant->suivant=new Cours();
  coursCourant=coursCourant->suivant;
  Etudiant *etudiantCourant=profCourant->listetudiants=new Etudiant();
  etudiantCourant->suivant=new Etudiant();
  etudiantCourant=etudiantCourant->suivant;
  t = new char [10]; 

  while(t[0]!='&' && !lecture.eof())
  {
   coursCourant->sigle = new char [10];
   lecture>> t ;
   strcpy (coursCourant->sigle,t);
   coursCourant->suivant=new Cours();
   coursCourant=coursCourant->suivant;
  }
  lecture>> t;
  while(t[0]!='&' && !lecture.eof())
  {
   etudiantCourant->nom = new char [25];
   strcpy (etudiantCourant->nom,t);
   lecture>> t;
   etudiantCourant->suivant=new Etudiant();
   etudiantCourant=etudiantCourant->suivant;
  }
  etudiantCourant->nom = new char [25]; 
  strcpy (etudiantCourant->nom,t);
  coursCourant->suivant= NULL;
  etudiantCourant->suivant= NULL;
  profCourant->suivant=new Professeur();
  profCourant = profCourant->suivant; 
  profCourant->suivant = NULL;
 }




 
}


void DossierProfesseur::affichage()
{
    Professeur *profCourant=tete;
    profCourant=profCourant->suivant;
    
    while(profCourant->suivant!=NULL)
    {
       
        cout << profCourant->nom      << endl;
        cout << profCourant->experience   << endl;
        cout << "------------------------------------------------" << endl;
        //liste des cours pour ce prof
        Cours *coursCourant=profCourant->listecours;
        while(coursCourant->suivant!=NULL)
        {
            coursCourant=coursCourant->suivant;
            cout << coursCourant->sigle << endl;
        }
  profCourant=profCourant->suivant;
    }
}


void  main()
{
   
 char option_menu[1];
 char text_option_menu[nb_charac_max];
 cout << "Quel action desirez vous effectuer? (- nom et prenom, *, % nom du cours, $ nom du fichier)";
 cin >> option_menu[0];
 cin.ignore(2, '[');
 cin.get(text_option_menu, nb_charac_max,']');




 switch(option_menu[0]){
 case '-':cout << "supprimer" << endl << text_option_menu << endl;break;
 case '*':cout << "nom plus demander";break;
 case '%':cout << "cours";break;
 case '$':cout << "sauvegarde";break;
 };


    DossierProfesseur *dossierProfesseur;
    dossierProfesseur= new DossierProfesseur("fp.txt");
    dossierProfesseur->affichage();


};
0
cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008
20 févr. 2007 à 19:39
le bug n'est pas là où tu crois. essais ça et tu verras

#include
#include <string.h>
#include<stdio.h>
#include <stdlib.h>
#include
#include <fstream.h>
const int nb_charac_max=80;
struct Cours
{
    char *sigle;
    Cours *suivant;
};

struct Etudiant
{
    char *nom;
    Etudiant *suivant;
};

struct Professeur
{
    char *nom;
    int experience;
    Cours *listecours;
    Etudiant *listetudiants;
    Professeur *suivant;
};

class DossierProfesseur
{
 
      
    public:
  Professeur *tete;
        DossierProfesseur(char *FP);
        ~DossierProfesseur();
  void affichage();
        //void supprimer(char *nom);
        //void afficherLaListe() const;
        char *afficherLeProfSuperviseEtudiant(char *nom) const;
        //char *afficherProfexperienceDuCoursPlusDemande(char *coursdonne) const;
        //int afficherCoursLePlusDemande() const;
        //void recopier(char *FP);
};
/*DossierProfesseur::
{
 

}*/

DossierProfesseur::DossierProfesseur(char *FP)
{
 char * t ;
 Professeur *profCourant=tete=new Professeur();
 printf( "2");
 profCourant->suivant=new Professeur();
 printf( "3");
 profCourant = profCourant->suivant;
 
 ifstream lecture(FP,ios::nocreate);
 
 if(lecture.fail())         //condition si l'ouverture envoie une erreur
 {
  cout<<"Erreur a l'ouverture du fichier"<<endl; //message d'erreur
  exit(1);          //sortir du programme lors d'une erreur
 }
 

 while(!lecture.eof())        //boucle qui lit jusqu'à la fin du fichier
 {
  //******************************************
  //*********bug ici au second tour***********
  printf(" again \n");
  profCourant->nom = new char[25];    
 
  printf("5");
  lecture.getline(profCourant->nom, 25);
  lecture>>profCourant->experience;  
  /********/
  printf("  %d   ", profCourant->experience );
  printf("**6");
  /********/
  Cours *coursCourant=profCourant->listecours=new Cours();
  coursCourant->suivant=new Cours();
  coursCourant=coursCourant->suivant;
  Etudiant *etudiantCourant=profCourant->listetudiants=new Etudiant();
  etudiantCourant->suivant=new Etudiant();
  etudiantCourant=etudiantCourant->suivant;
  t = new char [10];

  while(t[0]!='&' && !lecture.eof())
  {/*******/
    printf(" boucle1 \n");
    getchar();// pour voir la boucle infinie qui va etre crée la 2° entrer ds cette boucle
    /*********/
   coursCourant->sigle = new char [10];
   lecture>> t ;
   strcpy (coursCourant->sigle,t);
   coursCourant->suivant=new Cours();
   coursCourant=coursCourant->suivant;
  }
  lecture>> t;
  while(t[0]!='&' && !lecture.eof())
  {/*******/
    printf(" boucle2 \n");
    /********/
   etudiantCourant->nom = new char [25];
   strcpy (etudiantCourant->nom,t);
   lecture>> t;
   etudiantCourant->suivant=new Etudiant();
   etudiantCourant=etudiantCourant->suivant;
  }
  etudiantCourant->nom = new char [25];
  strcpy (etudiantCourant->nom,t);
  coursCourant->suivant= NULL;
  etudiantCourant->suivant= NULL;
  profCourant->suivant=new Professeur();
  profCourant = profCourant->suivant;
  profCourant->suivant = NULL;
 }

 
}

void DossierProfesseur::affichage()
{
    Professeur *profCourant=tete;
    profCourant=profCourant->suivant;
   
    while(profCourant->suivant!=NULL)
    {
        cout << profCourant->nom      << endl;
        cout << profCourant->experience   << endl;
        cout << "------------------------------------------------" << endl;
        //liste des cours pour ce prof
        Cours *coursCourant=profCourant->listecours;
        while(coursCourant->suivant!=NULL)
        {
            coursCourant=coursCourant->suivant;
            cout << coursCourant->sigle << endl;
        }
  profCourant=profCourant->suivant;
    }
}

void  main()
{
    DossierProfesseur *dossierProfesseur;
    dossierProfesseur= new DossierProfesseur("fp.txt");
    dossierProfesseur->affichage();
};
0
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
20 févr. 2007 à 20:02
je vois la boucle infini.. cependant je sais aussi que la boucle infinie n'est pas la cause , mais le résultat de la cause... La cause étant que les données ne sont plus lu après le premier tour de la boucle principale, ce qui cause la boucle infini... mais la raison pour laquelle les données ne sont plus lu m'est encore inconnue, et dès que je saurai le pourquoi et comment , il n'y aura plus de problème de boucle infini si le document texte est correct..  j'espère que ça aide quelqu'un à y voir plus clair parce que moi j'y vois rien, mais en tout les cas merci de l'intérêt apporté à mon problème
0
cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008
20 févr. 2007 à 20:24
salut pr le constructeur j'ai pu resoudre le probleme
mais la fonction d'affichage contient une erreur
0
martram Messages postés 17 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 2 décembre 2007
20 févr. 2007 à 21:18
salut
merci super beaucoup.. si tu serais une femme je t'embrasserais! :p
pour le problème de boucle d'affichage c'est parce ke t'as enlevé les
coursCourant->suivant= NULL;
etudiantCourant->suivant= NULL;

et mon problème était effectivement dans mes 2 sous boucles..
merci encore t'as fait un super travail!
0
cs_azamharir Messages postés 55 Date d'inscription jeudi 18 janvier 2007 Statut Membre Dernière intervention 1 novembre 2008
20 févr. 2007 à 21:36
salut
pour BEAUDOIN GUILLAUME  il ne lit que GUILLAUME.
donc, à la fin de la boucle grande boucle enleve lecture>> t ; et mets lecture.ignore();
à sa place et il lira BEAUDOIN GUILLAUME en entier.

et pour l'affichage c l'absence de machin.suivant->=NULL qui est la cause comme t'a pu le voir.

salut et ravi d'avoir pu t'aider. @+
0
Rejoignez-nous