2008-12-16 87 views
1

當出現單詞「同義詞」時,我想停止閱讀我的文本輸入文件。我正在使用ifstream,我不知道如何打破循環。我嘗試使用stringstream「同義詞」,但它結束了我的bst。如果您想避免打字,我會在下面列出完整的項目文件。如何打破閱讀這個文本文件(使用ifstream)? C++

重要組成部分:

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(如果你想運行它)

#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 

回答

2

你可以不喜歡它

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

注意,當它無法讀取一系列非空白字符,它會設置流的失敗位。那麼inStream的計算結果爲false。這就是循環的工作原理。使用.eof();時要小心,只有在您嘗試讀取超出文件末尾之後纔會返回true。因此,例如,你將退出循環,而錯過字3樹這裏:

1 house 2 garden 3 tree 

假設有後無空格。當然,如果你在單詞信息之間有換行符並且在最後一個單詞之後沒有結尾換行符,那麼當然會發生。使用if(inStream)(while循環隱含地)是安全的。在這種情況下,它仍然會被評估爲真,並且只有當它沒有讀取除空格之外的任何東西時才爲假。

+0

謝謝,這個作品最優雅。 – andandandand 2008-12-16 01:31:46

4

你應該讓運營商==上WORDINFO把它比作一個字符串,那麼你可以這樣在閱讀循環:

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

感謝,這讓我在路上。 :) – andandandand 2008-12-16 01:33:09

0

@SoapBox:

我創造了這個==操作符:

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

,並改變了對(;;)到:

for(;;) 
      { 


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

      wordTree.insert(word); 
      } 

而且結束了一個無限循環的印刷:

"Item already in the tree" 

順便說一句,我previoulsy用這樣的樣本字典測試樹,它的工作。

dict2.txt 

1可愛 2個招呼 3醜陋 4個簡單的 5困難 6累 7美麗