2009-01-25 97 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要灵活得多。