3

変数に値を割り当てることができないプログラムの失敗を特定しましたaddAntonymAnswer1cin.clear()ステートメントの前に実行して、yes/no答えを読み取らせようとしましたが、コードが応答しません。

失敗しているプログラムビットは内部に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;
      }
4

4 に答える 4

14

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」が含まれます。つまり、改行はまだ含まれています。2番目の行は、最初にすべての空白と改行をスキップして、の先頭にあるcin>>ことに対処できるようにします。これで、複数の呼び出しをシーケンスすることもできます。\nbargetline

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

Getlineは\n、行末で読み取ったものを破棄しますが、先頭の改行または空白を無視しません。したがって、最初のgetlineの後、バッファには「bar\n」が含まれます。2番目のgetlineも「bar\n」を正しく読み取ります。ここで、クリア/無視が必要な場合を考えてみましょう。

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

1つ目は、ストリームを「\ nbar\n」のままにします。次に、getlineは最初にすぐに表示さ\nれ、空の行を読み取ったと見なします。したがって、ストリームは「bar \ n」のままになり、すぐに続行され、何も待機しません。したがって、getlineアフターがあるcin>>場合は、最初に改行をクリアするために、クリア/無視シーケンスを実行する必要があります。しかし、getlineまたはcin>>の間に、あなたはそれをすべきではありません。

于 2009-01-25T21:25:45.580 に答える
1

cin >> ...空白文字が見つかるまで、標準入力から読み取ります。たとえば、8 5同義語のリストを入力すると、8読み込まれlineOfSyns、それ以上は何も表示されません。プログラムがに達するcin >> addAntonymAnswer1と、5に読み込まれaddAntonymsAnswer1ます。yesあなたのプログラムは、それが期待しているので、またはnoそれが得たので、予期せずに動作し5ます。

cin.getline()の代わりに使用することを検討してください>>。たとえば、 このページのセクション18.2および18.3を参照してください。

于 2009-01-25T21:39:07.910 に答える
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ます。ユーザーが「yes」または「no」と入力する機会は決してなく、これらの値のテストは失敗します。

読み取りを行う stringためにオーバーロードを使用するように変更することを検討する必要があります。getline()

getline( cin, stringvar);

これは、を使用するよりもおそらく優れています。これには、次cin.getline()のようなオーバーロードがないためstringです。そのメンバー関数では、文字の配列を読み取る必要があります。これは、を読み取るよりもはるかに柔軟性がありませんstring

于 2009-01-25T21:42:59.133 に答える
1

入力を待っているので「スタック」しています。cinはプログラムの標準入力ハンドルに接続されているので、何かを入力してEnterキーを押す必要があります。

于 2009-01-25T20:55:49.197 に答える