Liste chaînée avec Iterateur

Résolu
JeromeHanse - Modifié par cptpingu le 17/11/2013 à 14:05
 JeromeHanse - 17 nov. 2013 à 15:13
Bien le bonjour,

J'ai repris un code sur internet pour une liste chaînée avec iterateur. Après manipulation de celle-ci, je pense que je commence à cerner la logique.
Donc j'ai un switch pour : Ajout/listage/Sauvegarde de la fameuse liste.
Dans ajout, la fonction add fonctionne très bien, donc le problème ne vient pas de là.
Le problème est que, quand je passe dans la "case 2" ou "case 3", je ne peux revenir sur l'une d'elle, sinon mon programme plante ... Beaucoup !
Sans doute une incohérence de ma part avec l'iterateur..
Voici une partie du code: http://pastebin.com/Jr6p4tjD

  Iterator<Regate> it; 
  Liste<Regate> lreg;
  ......
  cout << "Choix: ";
  scanf ("%d",&choix);
  switch (choix)
  {
   case 1: Ajout(&lreg);
   break;
   case 2: Affich(lreg, it); 
  // ERREUR : JE NE PEUX PASSER QU UNE FOIS DS CASE 2 OU CASE 3.
   break;
   case 3: Sauvegarde (lreg, it);
   break;
   default : cout << "Vous devez faire un choix correcte ! 1 - 2 - 3." << endl;
  }

void Ajout(Liste<Regate> *lreg)
{
 Regate r;
 cout << " Ajout d'une regate" << endl;
 cin >> r;
 lreg->add(r);
 cout << "Verification d'ajout: ";
        if(lreg->contains(r)) // Vérification d'ajout.
        {
                cout << "SUCCESS" << endl;
        }
 else
 {
  cout << "FAILED" << endl;
 }
}
void Affich(Liste<Regate> lreg, Iterator<Regate> it)
{
 cout << "affich";
 Regate r;
 it = lreg.getIterator();
        while(it.hasNext())
        {
                std::cout << it.next() << std::endl;
        }
}

void Sauvegarde (Liste<Regate> lreg, Iterator<Regate> it)
{
 cout << "save!";
 fstream f;
 Regate r;
 it = lreg.getIterator(); 

 f.open("Regate.txt",ios::trunc|ios::out);
       while(it.hasNext())
    {
  f << it.next();
  i++;
      }
 f.close();
}



// Iterator.h
template <class E>
class Iterator
{
 private:
         Cellule<E>* curCell;

 public:
  Iterator()
  {
   curCell = NULL;
  }
         Iterator(Cellule<E>* cell)
         {
                 curCell = cell;
         }
         ~Iterator()
         {
         };
         bool hasNext()
         {
                 return curCell != NULL;
         }
         E next()
         {
                 E ret = curCell->data;
                 curCell = curCell->next;
                 return ret;
         }
};

// Dans liste.h : 
        Iterator<E> getIterator()
 {
                Iterator<E> it(firstCell);
                return it;
        }


Si vous remarquez un manque d'infos dans le code, n'hésitez pas.

Merci beaucoup !

Edit admin: Ajout du code.

2 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 17/11/2013 à 14:04
Bonjour.

Tout d'abord, n'hésite pas à copier coller du code ici, dans des balises de code, plutôt que sur un site externe (ce qui ne garantie pas la validité du lien à long terme).

Est-ce un exercice scolaire ? Parce que les listes chaînées existent déjà en C++.
Liste simplement chaînées: std::forward_list (à partir de C++11).
Liste doublement chaînées: std::list.

Quelques conseils:
- Evite les using namespace, voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
- Evite l'emploi de "NULL", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/null-en-cpp
- Utilise un std::ofstream, plutôt qu'un std::fstream + std::ios::out.
- Plutôt que scanf, utilise std::cin.
- Pas besoin de fclose(), un fstream se ferme tout seul à la sortie d'un scope.
- Les attributs de classe devrait être différenciés des variables. Généralement on met un "_" devant. curCell => _curCell
- Préfère l'utilisation de listes d'initialisation plutôt que de changer les valeurs dans le constructeur.
Ex:
Iterator()
{
  curCell = NULL;
}
Iterator(Cellule<E>* cell)
{
  curCell = cell;
}

Devrait être:
Iterator()
 : _curCell(0)
{
}
Iterator(Cellule<E>* cell)
 : _curCell(cell)
{
}

- S'il n'y a pas besoin de modifier un attribut au sein d'une méthode, on marque celle-ci en const:
bool hasNext()
{
  return curCell != NULL;
}

Devraît être:
bool hasNext() const
{
  return _curCell != 0;
}



Il y a des choses étrange dans ton code. Un coup tu passes ta liste en pointeur, un coup tu la passes en copie.
La fonction Affich, est très très bizarre...

// Pourquoi lreg est entièrement recopié, au lieu d'être passé par référence ou pointeur ?
void Affich(Liste<Regate> lreg, Iterator<Regate> it) // A quoi sert it, vu que tu ne te sers pas de la valeur ?
{
  cout << "affich";
  Regate r; // A quoi sert cette variable ?
  it = lreg.getIterator();
  while(it.hasNext())
  {
    std::cout << it.next() << std::endl;
  }
}
0
JeromeHanse
17 nov. 2013 à 15:13
Oui c'est un exercice scolaire, je code donc de la manière apprise au cours, donc c'est sur que ce n'est vraiment vraiment pas parfait ! En envoyant lreg en tant que référence dans la liste, a régler le problème du "plantage".

Je vous remercie donc! :)
0
Rejoignez-nous