Liste chaînée avec Iterateur [Résolu]

JeromeHanse - 17 nov. 2013 à 11:20 - Dernière réponse :  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.
Afficher la suite 

Votre réponse

2 réponses

cptpingu 3827 Messages postés dimanche 12 décembre 2004Date d'inscriptionModérateurStatut 6 octobre 2018 Dernière intervention - Modifié par cptpingu le 17/11/2013 à 14:04
0
Merci
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;
  }
}
Commenter la réponse de cptpingu
JeromeHanse - 17 nov. 2013 à 15:13
0
Merci
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! :)
Commenter la réponse de JeromeHanse

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.