Hello.
I have some troubles with a constructor, I can't figure out why a WHILE isn't working as I expected. The program stops there and it doesn't continue.
Thanks in advance.

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
 
struct Cours
{
    char sigle[7];
    Cours *suivant;
};
struct Etudiant
{
    char nom[20];
    Etudiant *apres;
};
struct Professeur
{
    char nom[20];
    char ancien[5];
    Cours *listecours;
    Etudiant *listetudiants;
    Professeur *suivant;
};
 
class DossierProfesseur
{
 
 
    public:
  Professeur *PTete;
        DossierProfesseur();
};
 
DossierProfesseur::DossierProfesseur()
{
 Professeur *PCourant, *PTete=NULL;
 Cours *PCoursCourant;
 Etudiant *PEtudiantCourant;
 string line;
 int y=1;
 ifstream myfile ("FP.txt");
 if (myfile.is_open())
 {
  while (! myfile.eof() )
  {  
   getline (myfile,line);
   PCourant = new Professeur;
   strcpy (PCourant->nom, line.c_str());
   getline (myfile, line);
   strcpy (PCourant->ancien, line.c_str());
   PCourant->listecours = new Cours;
   PCoursCourant=PCourant->listecours;
[B] while (line!="&")[/B]
[B] {      [/B]
[B]  getline (myfile,line);[/B]
[B]  strcpy (PCoursCourant->sigle, line.c_str());[/B]
[B]  cout <<y <<line <<endl;[/B]
[B]  y++;[/B]
[B]  PCoursCourant->suivant = new Cours;[/B]
[B] }[/B]
   line="clean";
   cout<<line;
   PCourant->listetudiants = new Etudiant;
   PEtudiantCourant=PCourant->listetudiants;
   while (line!="&")
   {
    getline (myfile,line);
    strcpy (PEtudiantCourant->nom, line.c_str());
    cout << PEtudiantCourant->nom;
    PCoursCourant->suivant = new Cours;
   }
   line="clean";
   PCourant->suivant=PTete;
   PTete=PCourant;
  }
  myfile.close();
 }
 else cout << "Unable to open file";
}
 
 
}*/
 
void main () {
 
    DossierProfesseur *dossierProfesseur;    
    dossierProfesseur= new DossierProfesseur;
 
}

and the file text is something like:
TEACHER
TEACHING EXPERIENCE
CLASSES
SEPARATOR
ESTUDENTS
SEPARATOR

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

I can't really tell what your code is supposed to be doing; please forgive me. For testing purposes I changed myFile to cin so I could manually enter the input. It seemed to work as expected, stopping whenever it reached a '&' character.

One thing that I noticed was that you're doing something very, very BAD. Whenever you copy a C++ string with strcp(), you never check to make sure that the length of it is shorter than the size of the C string you're trying to copy into. Ideally you would dynamically allocate the memory as Ancient Dragon suggested in the previous thread.

Or just check that line.size() is not too large. Anyway, to prove my point, I got your program to crash as a result of inputting large strings. So keep that in mind, as that may have been what was screwing up your program,

By the way, you never mentioned what did actually happen when you ran it. Care to say so we know exactly what you're having problems with?

Oh, I just noticed something!

PCoursCourant->suivant = new Cours;

Where in that loop do you actually advance the pointer to the node that you allocate? You're just reallocating the same pointer, causing memory leaks for sure.

Hello.
I have some troubles with a constructor, I can't figure out why a WHILE isn't working as I expected. The program stops there and it doesn't continue.
Thanks in advance.

[B]while (line!="&")[/B]
[B]{      [/B]
[B] getline (myfile,line);[/B]
[B] strcpy (PCoursCourant->sigle, line.c_str());[/B]
[B] cout <<y <<line <<endl;[/B]
[B] y++;[/B]
[B] PCoursCourant->suivant = new Cours;[/B]
[B]}[/B]

You've got to be careful when you're using linked lists. One obvious problem is that you're allocating a new Cours on the heap and assigning it to the "suivant" variable. But you forgot to set PCoursCourant to suivat. Try this for starters:

while (line!="&")
{
 getline(myfile,line);
 strcpy(PCoursCourant->sigle,line.c_str));
cout << y << line << endl;
y++;
PCoursCourant->suivant = new Cours;
PCoursCourant = PCoursCourant->suivant;
PCoursCourant->suivant = NULL;
}

Thanks for your help.
Joe:
The program should construct a linked list with the teachers' stats (names, teaching years, another linked list for his/her classes and another linked list for his students).
In fact the classs Professeur should have functions like constructor, destructor, an output screen, and another things, but as you can see I'm stuck in the constructor. The COUTs shouldnt be there, there are only for testing.
The error is that I expected to obtain:

1SIF100
2SIF102
3SIF104
4SIF106
stop for the character "&"and continue with the next teacher's classes

but I'm getting:
1SIF100
2SIF102
3SIF104
4SIF106
5&
6BOUDREAULT
7COTE
...

I didn't expected that the & was read nor the students

Lazaro Claiborn:
I have tried your code, it produces an infinite loop, I don't know why.

The thing taht I want is just that the while stop when line="&".
Do you know why it is not working?

Lazaro Claiborn:
I have tried your code, it produces an infinite loop, I don't know why.

So the program loops until the & character is met; by the way you might want to try while (strcmp(line.c_str(), "&") == 0) - that might work. It gets the next line of the file opened and referrenced by myfile and puts it into the line variable of type string. It then extracts the Cstyle string from line and copies it into the sigle property pointed by PCoursCourant which holds the address a Cours type allocated on the heap. Once copied, it prints y and line to standard output and inserts and end-of-line. Post increments the y variable. Then it allocates a new Cours instance and passes that address to the suivant also of type Cours.

Ok when it loops again, the PCoursCourant hasn't changed it still points to the same instance as the previous. Surely you know a pointer variable can contain a value of NULL. All I simply do is pass the suivant of the current PCoursCourant instance to the parent PCoursCourant itself. Then I pass the suivant of the recently allocated instance the NULL value.

Your way:

Loop through:
[ PCoursCourant ] --[ suviant ] -- new Cours;

My way:

Loop through:
[ PCoursCourant ] -- [ suviant ] -- new Cours;
[ PCoursCourant ] = [ PCoursCourant ] -- suviant;
[ PCoursCourant ] -- [ suviant ] = NULL;

This modification itself shouldn't directly produce an infinite loop. Also, might I suggest you avoid having the constructor itself read from the file, one line at a time, and pass the read values into there designated fields and instead write private function(s) that'll do it for you. I find it that when a class and its member functions are more organized, it is easier to read and understand. Last, and already mentioned, you'll have to iterate through the linked lists and free or delete them probably in the destructor of the class.

Good luck, LamaBot

Finally my partner has saved the day doing the constructor.
Now I try to code a function that show the student who takes classes with more teachers. We have the constructor and the main function, but I'll paste only the issue and the struct.

In bold you will find the problematic line, I'm trying to compare two strings.

#include <iostream>
# include <iomanip>
#include <cctype>
#include <cstring>
#include <fstream>
#include <memory>

#include <stdio.h>
#include <string.h>
using namespace std;


struct type_cours {
   char  *sigle;
   type_cours *PtrSuivant;
};

struct  type_etudiant {
   char   *nom;
   type_etudiant *PtrSuivant;
};


struct  type_professeur{
   char *nom;
   char *prenom;
   int  experience;
   type_cours *PtrListcours;
   type_etudiant *PtrListetudiants;
   type_professeur *PtrSuivant;
};


class DossierProfesseur
{
           
    public:
        type_professeur *PtrTete;

        DossierProfesseur();  
        void affichage();
        void afficherEtudiantPlus ();
};


///////////////////////////////////////////
//        ETUDIANT PLUS DEMANDE   //
///////////////////////////////////////////

void DossierProfesseur::afficherEtudiantPlus()
{
    type_professeur *PtrProf;
    type_etudiant*PtrEtudiant;
    PtrProf=PtrTete;
    struct type_demande {
    string  etudiantdem;
    int max;
    };
    type_demande Demande[20];
    int Taille=0, y;
    bool Etat;

    for (y=0; y<20; y++)
        Demande[y].max=0;
    do
    {        
        PtrEtudiant=PtrProf->PtrListetudiants;
        do
        {
            for (y=0, Etat=false; y<Taille; y++)
            {

                [B]if(strcmp (PtrEtudiant->nom, Demande[y].etudiantdem) != 0)[/B]
                {
                    Demande[y].max++;
                    Etat=true;
                }
            }
            if (Etat==false)
            {
                Demande[Taille].etudiantdem=PtrEtudiant->nom;
                Taille++;
                cout<<PtrEtudiant->nom;
            }
            PtrEtudiant=PtrEtudiant->PtrSuivant;
        }while(PtrEtudiant->nom!=NULL);
    }while(PtrProf->PtrSuivant!=NULL);

}

Thanks

...and? What happens?

Do you get a syntax error, runtime error/memory leak; what's the problem? Post any error messages you receive, whether they be from the program's output, or just from the compiler's error window.

Sorry.
I get this error:
error C2664: 'strcmp' : cannot convert parameter 2 from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'const char *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Ah. The second parameter (Demande[y].etudiantdem) is a std::string, not a C-style string. To use it in strcmp(), you'll need the c_str() member function of std::string:

strcmp(PtrEtudiant->nom, Demande[y].etudiantdem.c_str());
This article has been dead for over six months. Start a new discussion instead.