2009-01-25 99 views
2

我已經指出了我的程序失敗,導致我無法爲變量addAntonymAnswer1分配一個值。我已經試過在聲明前運行cin.clear(),以便讀取我的yes/no答案,但代碼不會迴應。爲什麼這個cin閱讀被卡住了?

多數民衆贊成遇事位於內void dictionaryMenu(vector <WordInfo> &wordInfoVector)和讀取

  cin.clear(); 

     cout<<">"; 
     cin>>addAntonymAnswer1; 

     // cin reading STUCK, why!? 

讓用戶有權利選擇添加一個字,程序的點,然後添加一個同義詞的程序位。

運行程序的輸入是:

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

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

#include <sstream> 
#include <vector> 


using namespace std; 



class WordInfo{ 

     public: 

      WordInfo(){} 

      WordInfo(string newWord){ 
          word=newWord;     
      } 

      ~WordInfo() { } 

      int id() const {return myId;} 

      void readWords(istream &in) 
      { 
       in>>myId>>word;  
      } 

      vector <int> & getSynonyms() { 

        return mySynonyms; 
      } 

      vector <int> & getAntonyms() { 

        return myAntonyms; 
      } 

      string getWord() { 
        return word; 
        } 


      void dictionaryMenu (vector <WordInfo> &wordInfoVector){ 

      cout<<endl<<"Would you like to add a word?"<<endl; 
      cout<<"(yes/no)"<<endl; 
      cout<<">"; 
      string addWordAnswer; 
      cin>>addWordAnswer; 

      if (addWordAnswer=="yes") 
      // case if the guy wants to add a word 
      { 
      cout<<endl;     
      cout<<"Please, write the word "<<endl;     

      string newWord; 
      cout<<">"; 
      cin>>newWord; 
      cout<<endl;   

      WordInfo newWordInfo (newWord); 

      int newWordId = wordInfoVector.size() +1; 

      newWordInfo.myId=newWordId; 

      cout<<"The id of "<<newWordInfo.word<<" is "<<newWordInfo.myId<<endl<<endl; 

      wordInfoVector.push_back(newWordInfo); 


      cout<<"Would you like to define which words on the existing dictionary are" <<endl 
      <<"synonyms of "<<newWordInfo.word<<"?"<<endl; 


      cout<<"(yes/no)"<<endl; 

      string addSynonymAnswer, addAntonymAnswer1, addAntonymAnswer2; 
      cout<<">"; 
      cin>>addSynonymAnswer; 




      if (addSynonymAnswer=="yes") 
      { 

      cout<<endl; 
      cout<<"Please write on a single line the ids for the synonyms of " 
      <<newWordInfo.word<<endl<<"starting with its id, which is "<<newWordInfo.myId<<endl<<endl; 

      cout<<"For example, to define that the synonym of the word 'cute', which has an id 1, is" 
      <<"'beautiful', which has an id 7, you should write: 1 7"<<endl<<endl; 

      cout<<"In the case of "<<newWordInfo.word<<" you should start with "<<newWordInfo.myId<<endl; 

      cin.clear(); 
      string lineOfSyns; 
      cout<<">"; 

      cin>>lineOfSyns; 

      newWordInfo.pushSynonyms(lineOfSyns, wordInfoVector); 

      cin.clear();  


       cout<<"Would you like to define which words on the existing dictionary are" <<endl 
       <<"antonyms of "<<newWordInfo.word<<"?"<<endl; 

        //##HERE THE CIN READING OF addAntonymAnswer1 FAILS, WHY? 

       cin.clear(); 
       cout<<">"; 
       cin>>addAntonymAnswer1; 

       // cin reading STUCK, why!? 


       if (addAntonymAnswer1=="yes"){ }       

        else if (addAntonymAnswer1=="no"){ 
         // END DICTIONARY MENU 
         }     
      } 
      else if (addSynonymAnswer=="no"){ 

       cout<<"Would you like to define which words on the existing dictionary are" <<endl 
       <<"antonyms of "<<newWordInfo.word<<"?"<<endl; 


       cout<<">"; 
       cin>>addAntonymAnswer2; 

       if (addAntonymAnswer2=="yes"){ }       

        else if (addAntonymAnswer2=="no"){ 
         // END DICTIONARY MENU 
         } 

      } 


      } // if addWordAnswer == "no" 

      else if (addWordAnswer=="no"){ 

       // ######RETURN TO MAIN MENU############ 
       }   






      } 

      void pushSynonyms (string synline, vector<WordInfo> &wordInfoVector){ 


      stringstream synstream(synline); 

      vector<int> synsAux; 

      // synsAux tiene la línea de sinónimos 

      int num; 

      while (synstream >> num) {synsAux.push_back(num);} 

      int wordInfoVectorIndex; 

      int synsAuxCopyIndex; 



      if (synsAux.size()>=2){ // takes away the runtime Error 



      for (wordInfoVectorIndex=0; wordInfoVectorIndex <wordInfoVector.size(); wordInfoVectorIndex++) 
      { 


       if (synsAux[0]==wordInfoVector[wordInfoVectorIndex].id()){ 


        // this is the line that's generating a Runtime Error, Why?              
        for (synsAuxCopyIndex=1; synsAuxCopyIndex<synsAux.size(); synsAuxCopyIndex++){ 

        // won't run yet  
        wordInfoVector[wordInfoVectorIndex].mySynonyms.push_back(synsAux[synsAuxCopyIndex]);  
         }               
       }  
      } 

      }// end if size()>=2 


      } // end pushSynonyms 








      void pushAntonyms (string antline, vector <WordInfo> &wordInfoVector) 
      { 



      stringstream antstream(antline); 

      vector<int> antsAux; 

      int num; 

      while (antstream >> num) antsAux.push_back(num); 


      int wordInfoVectorIndex; 

      int antsAuxCopyIndex; 



      if (antsAux.size()>=2){ // takes away the runtime Error    

      for (wordInfoVectorIndex=0; wordInfoVectorIndex <wordInfoVector.size(); wordInfoVectorIndex++) 
      { 


       if (antsAux[0]==wordInfoVector[wordInfoVectorIndex].id()){ 


        // this is the line that's generating a Runtime Error, Why?              
        for (antsAuxCopyIndex=1; antsAuxCopyIndex<antsAux.size(); antsAuxCopyIndex++){ 

        // won't run yet  
        wordInfoVector[wordInfoVectorIndex].myAntonyms.push_back(antsAux[antsAuxCopyIndex]);  
         }               
       }  
      } 

      }// end if size()>=2 





      } 

      //--dictionary output function 

      void printWords (ostream &out) 
      { 
       out<<myId<< " "<<word;  
      } 



      //--equals operator for String 
      bool operator == (const string &aString)const 
      { 
          return word ==aString; 

      } 


      //--less than operator 

      bool operator <(const WordInfo &otherWordInfo) const 
      { return word<otherWordInfo.word;} 

      //--more than operator 

      bool operator > (const WordInfo &otherWordInfo)const 
      {return word>otherWordInfo.word;} 

      public: 

        vector<int> mySynonyms; 
        vector <int> myAntonyms; 


        string word; 
        int myId; 


     }; 

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

     } 



     //--Definition of output operator 

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

     } 





     int main() { 

      string wordFile; 
      cout<<"enter name of dictionary file: "<<endl; 
      getline (cin,wordFile); 

      ifstream inStream (wordFile.data()); 

      if(!inStream.is_open()) 
      { 
      cerr<<"cannot open "<<wordFile<<endl; 
      exit(1);      

      } 

      vector <WordInfo> wordInfoVector; 

      WordInfo aword; 





      while (inStream >>aword && (!(aword=="synonyms"))) 
      { 
       wordInfoVector.push_back(aword); 


      } 

      inStream.clear(); 









      vector <int> intVector; 
      string synLine; 






      while (getline(inStream, synLine)&&(synLine!=("antonyms"))){ 

       aword.pushSynonyms(synLine, wordInfoVector); 

       } 



      int theIndex; 



      string antLine; 

      while (getline(inStream,antLine)){ 

       aword.pushAntonyms(antLine, wordInfoVector); 
       }  



      cout<<endl<<"the words on the dictionary are: "<<endl; 

      int h=0;   
      while (h<wordInfoVector.size()){ 
       cout<<wordInfoVector[h]<<endl; 
       h++; 
       } 

      aword.dictionaryMenu(wordInfoVector); 

      system("PAUSE"); 

      return 0; 
     } 

回答

13

cin.clear()不清除標準輸入。它所做的是清除錯誤位,如eofbit,failbit等,並將流設置爲良好狀態。也許你期望它清除任何內容?如果用戶鍵入

yes no 

就在,你

cin >> someStringVariable; 

它會讀取多達no和流仍將包含

no 

clear呼叫然後清除任何錯誤位處於活動狀態。然後,你

cin>>addAntonymAnswer1; 

會讀,這不是由以前讀吃了no,動作立即返回,而不是等待新的輸入。你應該做的是做一個clear然後忽略,直到下一個換行符。你告訴它它應該最大限度地忽略的字符數量。這一數額應該是最高的數字可能:

cin.clear(); 
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

這樣做,這將使流空,和下面的內容將等待你輸入的東西,如果你有


另一個問題得到了一個cin >>後面跟着一個getline:cin會在其讀取令牌後留下任何空格(也包括換行符),但getline會在遇到這樣的換行符後停止讀取。我看到幾乎所有東西都放在了clear之後。所以我想告訴你什麼時候需要它,什麼時候不需要。當您對多個cin >>進行測序時,您不需要它。假設你的緩衝區中有:「foo \ nbar \ n」。然後你做下面的讀取

cin >> a; // 1 
cin >> b; // 2 

在第一個之後,你的緩衝區將包含「\ nbar \ n」。也就是說,換行符還在。第二個cin>>將首先跳過所有空格和換行符,以便它可以應對位於bar前面的\n。現在,你也可以多序列來電getline

getline(cin, a); 
getline(cin, b); 

函數getline會扔掉它讀取行端的\n,但不會忽略在開始換行或空白。所以,在第一個getline之後,緩衝區包含「bar \ n」。第二個getline也會正確讀取「bar \ n」。現在,讓我們考慮的情況下,你需要清晰/忽略:

cin >> a; 
getline(cin, b); 

第一個將離開流爲「\ NBAR \ N」。 getline然後會在開始時立即看到\n,並且會認爲它讀取了一個空行。因此,它會立即繼續,而不是等待任何東西,將流留下爲「bar \ n」。因此,如果您在cin>>之後有getline,則應首先執行清除/忽略序列,以清除換行符。但是在getlinecin>>之間,你不應該這樣做。

1

這是 「卡住」,因爲它在等待輸入。 cin附加到程序的標準輸入句柄上,你必須輸入一些東西然後回車。

+0

我的意思是「卡住」,它不讓我「鍵入內容並回車」。控制檯立即呈現「按任意鍵繼續」。 – andandandand 2009-01-25 20:58:38

+1

我不認爲他應該得到一個downvote。 「卡住」意味着它不會繼續,我認爲他正確解釋。相反,也許改變你的問題的措辭。 – 2009-01-25 21:28:17

+1

它假定海報不知道「cin附加到程序的標準輸入句柄,你必須輸入一些東西,然後回車」,我覺得這有點冒犯了,這個人甚至沒有讀我的代碼。 – andandandand 2009-01-25 21:39:07

1

cin >> ...從標準輸入讀取,直到找到空白字符。當您輸入8 5作爲同義詞列表時,8會被讀入lineOfSyns,僅此而已。當程序到達cin >> addAntonymAnswer1時,5被讀入addAntonymsAnswer1。你的程序行爲意外,因爲它期望yesno但它得到5

請看使用cin.getline()而不是>>。例如參見this page的第18.2和18.3節。

1

在你的程序,你問用戶:

Please write on a single line the ids for the synonyms of test 
starting with its id, which is 8 

For example, to define that the synonym of the word 'cute', which has an id 1, i 
s'beautiful', which has an id 7, you should write: 1 7 

In the case of test you should start with 8 

然後嘗試在該行讀取與

cin>>lineOfSyns; 

但是輸入的用戶來說,這隻能讀取到第一個空格。因此,用戶鍵入的第2個數字仍然在cin緩衝當

cin>>addAntonymAnswer1; 

線被執行,從而使數據被讀入addAntonymAnswer1字符串。用戶從來沒有機會輸入「是」或「否」,並且對這些值的測試失敗。

你應該考慮改變使用string重載getline()做您寫着:

getline(cin, stringvar); 

這很可能會比使用cin.getline()更好,因爲這不具有重載需要string - 與那名成員函數,你需要讀入一個字符數組,這比讀入string要靈活得多。