2008-12-16 4 views
1

Je veux arrêter la lecture de mon fichier d'entrée de texte lorsque le mot "synonymes" apparaît. J'utilise ifstream et je ne sais pas comment casser la boucle. J'ai essayé d'utiliser un "synonyme" de stringstream mais il a fini par se faufiler dans mon bst. J'ai inclus les fichiers de projet complets ci-dessous au cas où vous voulez éviter de taper.Comment puis-je interrompre la lecture de ce fichier texte (en utilisant ifstream)? C++

partie Important:

for(;;) /*here, I wanna break the cycle when it reads "synonyms"*/ 
       { 

       inStream >> word; 
       if (inStream.eof()) break; 

       wordTree.insert(word); 
       } 

       wordTree.graph(cout); 

dictionary.txt

1 cute 
    2 hello 
    3 ugly 
    4 easy 
    5 difficult 
    6 tired 
    7 beautiful 
    synonyms 
    1 7 
    7 1 
    antonyms 
    1 3 
    3 1 7 
    4 5 
    5 4 
    7 3 

Project.cpp

#include <iostream> 
#include <fstream> 
#include <string> 
#include <sstream> 

#include "MiBST.h" 

using namespace std; 

class WordInfo{ 

     public: 
     //--id accesor 
     int id()const {return myId; } 

     /* myId is the number that identifies each word*/ 

     //--input function 
     void read (istream &in) 
     { 
     in>>myId>>word;  
     } 

     //--output function 
     void print(ostream &out) 
     { 
      out<<myId<<" "<<word;  
     } 

     //--- equals operator 
    bool operator==(const WordInfo & otherword) const 
    { return myId == otherword.myId; } 

    //--- less-than operator 
     bool operator<(const WordInfo & otherword) const 
     { return myId < otherword.myId; } 


     private: 
       int myId; 
       string word; 

     }; 

     //--- Definition of input operator 
     istream & operator>>(istream & in, WordInfo & word) 
     { 
      word.read(in); 
     } 

     //---Definition of output operator 

     ostream & operator <<(ostream &out, WordInfo &word) 
     { 
      word.print(out);  
     } 

     int main(){ 

      // Open stream to file of ids and words 
      string wordFile; 

      cout << "Enter name of dictionary file: "; 
      getline(cin, wordFile); 

      ifstream inStream(wordFile.data()); 



      if (!inStream.is_open()) 
      { 
      cerr << "Cannot open " << wordFile << "\n"; 
      exit(1); 
      } 


      // Build the BST of word records 
      BST<WordInfo> wordTree; // BST of word records 

      WordInfo word;   // a word record 



      for(;;) /*here, I wanna break the cycle when it reads "synonyms"*/ 
      { 

      inStream >> word; 
      if (inStream.eof()) break; 

      wordTree.insert(word); 
      } 

      wordTree.graph(cout); 

      //wordTree.inorder(cout); 


      system ("PAUSE"); 
      return 0; 

     } 

MiBST.h (au cas où vous voulez l'exécuter)

#include <iostream> 
#include <iomanip> 

#ifndef BINARY_SEARCH_TREE 
#define BINARY_SEARCH_TREE 




template <typename DataType> 
class BST 
{ 
public: 
    /***** Function Members *****/ 
    BST(); 

    bool empty() const; 

    bool search(const DataType & item) const; 

    void insert(const DataType & item); 

    void remove(const DataType & item); 

    void inorder(std::ostream & out) const; 

    void graph(std::ostream & out) const; 

    private: 
    /***** Node class *****/ 
    class BinNode 
    { 
    public: 
    DataType data; 
    BinNode * left; 
    BinNode * right; 

    // BinNode constructors 
    // Default -- data part is default DataType value; both links are null. 
    BinNode() 
    : left(0), right(0) 
    {} 

    // Explicit Value -- data part contains item; both links are null. 
    BinNode(DataType item) 
    : data(item), left(0), right(0) 
    {} 


}; //end inner class 

typedef BinNode * BinNodePointer; 

    /***** Private Function Members *****/ 
    void search2(const DataType & item, bool & found, 
       BinNodePointer & locptr, BinNodePointer & parent) const; 
/*------------------------------------------------------------------------ 
    Locate a node containing item and its parent. 

    Precondition: None. 
    Postcondition: locptr points to node containing item or is null if 
     not found, and parent points to its parent.#include <iostream> 
------------------------------------------------------------------------*/ 

    void inorderAux(std::ostream & out, 
        BST<DataType>::BinNodePointer subtreePtr) const; 
    /*------------------------------------------------------------------------ 
    Inorder traversal auxiliary function. 

    Precondition: ostream out is open; subtreePtr points to a subtree 
     of this BST. 
    Postcondition: Subtree with root pointed to by subtreePtr has been 
     output to out. 
------------------------------------------------------------------------*/ 

    void graphAux(std::ostream & out, int indent, 
         BST<DataType>::BinNodePointer subtreeRoot) const; 
    /*------------------------------------------------------------------------ 
    Graph auxiliary function. 

    Precondition: ostream out is open; subtreePtr points to a subtree 
     of this BST. 
    Postcondition: Graphical representation of subtree with root pointed 
     to by subtreePtr has been output to out, indented indent spaces. 
------------------------------------------------------------------------*/ 

/***** Data Members *****/ 
    BinNodePointer myRoot; 

}; // end of class template declaration 

//--- Definition of constructor 
template <typename DataType> 
inline BST<DataType>::BST() 
: myRoot(0) 
{} 

//--- Definition of empty() 
template <typename DataType> 
inline bool BST<DataType>::empty() const 
{ return myRoot == 0; } 

//--- Definition of search() 
template <typename DataType> 
bool BST<DataType>::search(const DataType & item) const 
{ 
    typename BST<DataType>::BinNodePointer locptr = myRoot; 

    typename BST<DataType>::BinNodePointer parent =0; 

/* BST<DataType>::BinNodePointer locptr = myRoot; 
    parent = 0; */ //falta el typename en la declaracion original 

    bool found = false; 
    while (!found && locptr != 0) 
    { 
     if (item < locptr->data)  // descend left 
     locptr = locptr->left; 
     else if (locptr->data < item) // descend right 
     locptr = locptr->right; 
     else       // item found 
     found = true; 
    } 
    return found; 
} 

//--- Definition of insert() 
template <typename DataType> 
inline void BST<DataType>::insert(const DataType & item) 
{ 
    typename BST<DataType>::BinNodePointer 
     locptr = myRoot, // search pointer 
     parent = 0;  // pointer to parent of current node 
    bool found = false;  // indicates if item already in BST 
    while (!found && locptr != 0) 
    { 
     parent = locptr; 
     if (item < locptr->data)  // descend left 
     locptr = locptr->left; 
     else if (locptr->data < item) // descend right 
     locptr = locptr->right; 
     else       // item found 
     found = true; 
    } 
    if (!found) 
    {         // construct node containing item 


     locptr = new typename BST<DataType>::BinNode(item); 
     if (parent == 0)    // empty tree 
     myRoot = locptr; 
     else if (item < parent->data) // insert to left of parent 
     parent->left = locptr; 
     else       // insert to right of parent 
     parent->right = locptr; 
    } 
    else 
     std::cout << "Item already in the tree\n"; 
} 

//--- Definition of remove() 
template <typename DataType> 
void BST<DataType>::remove(const DataType & item) 
{ 
    bool found;      // signals if item is found 
    typename BST<DataType>::BinNodePointer 
     x,       // points to node to be deleted 
     parent;      // " " parent of x and xSucc 
    search2(item, found, x, parent); 

    if (!found) 
    { 
     std::cout << "Item not in the BST\n"; 
     return; 
    } 
    //else 
    if (x->left != 0 && x->right != 0) 
    {        // node has 2 children 
     // Find x's inorder successor and its parent 
     typename BST<DataType>::BinNodePointer xSucc = x->right; 
     parent = x; 
     while (xSucc->left != 0)  // descend left 
     { 
     parent = xSucc; 
     xSucc = xSucc->left; 
     } 

    // Move contents of xSucc to x and change x 
    // to point to successor, which will be removed. 
    x->data = xSucc->data; 
    x = xSucc; 
    } // end if node has 2 children 

    // Now proceed with case where node has 0 or 2 child 
    typename BST<DataType>::BinNodePointer 
     subtree = x->left;    // pointer to a subtree of x 
    if (subtree == 0) 
     subtree = x->right; 
    if (parent == 0)     // root being removed 
     myRoot = subtree; 
    else if (parent->left == x)  // left child of parent 
     parent->left = subtree; 
    else        // right child of parent 
     parent->right = subtree; 
    delete x; 
} 

//--- Definition of inorder() 
template <typename DataType> 
inline void BST<DataType>::inorder(std::ostream & out) const 
{ 
    inorderAux(out, myRoot); 
} 

//--- Definition of graph() 
template <typename DataType> 
inline void BST<DataType>::graph(std::ostream & out) const 
{ graphAux(out, 0, myRoot); } 

//--- Definition of search2() 
template <typename DataType> 
void BST<DataType>::search2(const DataType & item, bool & found, 
          BST<DataType>::BinNodePointer & locptr, 
          BST<DataType>::BinNodePointer & parent) const 
{ 
    locptr = myRoot; 
    parent = 0; 
    found = false; 
    while (!found && locptr != 0) 
    { 
     if (item < locptr->data)  // descend left 
     { 
     parent = locptr; 
     locptr = locptr->left; 
     } 
     else if (locptr->data < item) // descend right 
     { 
     parent = locptr; 
     locptr = locptr->right; 
     } 
     else       // item found 
     found = true; 
    } 
} 
//--- Definition of inorderAux() 
template <typename DataType> 
void BST<DataType>::inorderAux(std::ostream & out, 
           BST<DataType>::BinNodePointer subtreeRoot) const 
{ 
    if (subtreeRoot != 0) 
    { 
     inorderAux(out, subtreeRoot->left); // L operation 
     out << subtreeRoot->data << " ";  // V operation 
     inorderAux(out, subtreeRoot->right); // R operation 
    } 
} 


//--- Definition of graphAux() 


template <typename DataType> 
void BST<DataType>::graphAux(std::ostream & out, int indent, 
          BST<DataType>::BinNodePointer subtreeRoot) const 
{ 
    if (subtreeRoot != 0) 
    { 
     graphAux(out, indent + 8, subtreeRoot->right); 
     out << std::setw(indent) << " " << subtreeRoot->data << std::endl; 
     graphAux(out, indent + 8, subtreeRoot->left); 
    } 
} 


#endif 

Répondre

2

Vous pouvez le faire comme

/* here, it stops when reading "synonyms" or when failing to extract a word. */ 
while(inStream >> word && word != "synonym") { 
    wordTree.insert(word); 
} 
wordTree.graph(cout); 

Notez que lorsque il ne parvient pas à lire une séquence de caractères non-espaces, il définit le bit de défaillance du flux. inStream évalue à false alors. C'est ce qui fait fonctionner la boucle. Soyez prudent lors de l'utilisation .eof(); Il retourne seulement vrai après avoir essayé de lire au-delà de la fin du fichier. Ainsi, par exemple, vous sortir de la boucle, et manquer le mot 3 arbre ici:

1 house 2 garden 3 tree 

Si l'on suppose qu'il n'y a pas d'espace blanc après arbre. La même chose se produira bien sûr si vous avez des sauts de ligne entre les informations du mot et que vous n'avez pas de nouvelle ligne après le dernier mot. L'utilisation de if(inStream) (que la boucle while fait implicitement) est sûre. Il serait toujours vrai à vrai dans ce cas, et seulement à faux s'il ne lisait rien excepté l'espace blanc.

+0

merci, cela fonctionne le plus élégamment. – andandandand

4

Vous devriez faire un opérateur == sur WordInfo pour le comparer à une chaîne, vous pouvez tout cela dans la boucle de lecture:

if (word == "synonyms") break; 
+0

merci, il m'a mis sur le chemin. :) – andandandand

0

@SoapBox:

J'ai créé cet opérateur ==:

//--- equals operator for String 
    bool operator==(const string & aString) const 
    { return word == aString; } // word is the WordInfo string field for 'real' word 

Et changé le for (;;) à:

for(;;) 
      { 


      inStream >> word; 
      if (word=="synonyms") break; 

      wordTree.insert(word); 
      } 

et a fini avec une impression de boucle infinie :

"Item already in the tree" 

Btw, j'ai déjà testé l'arbre avec un exemple de dictionnaire comme celui-ci et cela a fonctionné.

dict2.txt 

1 mignon 2 bonjour 3 laid 4 facile 5 difficile 6 fatigués 7 belles

Questions connexes