为什么这个cin阅读卡住了?
我已经指出了一个失败,我的程序,阻止我分配一个值的variablesaddAntonymAnswer1
。 我已经尝试了在语句之前运行cin.clear()
,以便读取我的yes/no
回答,但是代码不会回应。
失败的程序位于void dictionaryMenu(vector <WordInfo> &wordInfoVector)
并读取
cin.clear(); cout<<">"; cin>>addAntonymAnswer1; // cin reading STUCK, why!?
要到达程序的那一点,用户必须select添加一个单词,然后添加一个同义词。
运行程序的input是:
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; }
cin.clear()
不会清除标准input。 它所做的是清除错误位,如eofbit
, failbit
等,并将stream设置为良好的状态。 也许你期望它清除任何东西? 如果用户input
yes no
就在和你在一起
cin >> someStringVariable;
它将读取到no
,stream将仍然包含
no
清除的调用清除任何错误位。 那么,你的
cin>>addAntonymAnswer1;
将读取前一次读取的no
被吃掉的行为,并且行动立即返回,而不是等待新的input。 你应该做的是做一个clear
然后忽略,直到下一个换行符。 你告诉它应该忽略最多的字符数量。 这个数字应该是可能的最高数字:
cin.clear(); cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
这样做会使stream空,下面的阅读将等待你input的东西。
另一个问题是,如果你有一个cin >>
后跟一个getline
:cin会在其读取标记之后留下任何空格(也包括换行符),但是getline
在它到达这样一个换行符后将停止读取。 我看你已经把几乎所有东西都clear
了。 所以我想告诉你什么时候需要它,什么时候不需要。 当你对多个cin >>
sorting时,你不需要它。 假设你在你的缓冲区中有:“foo \ nbar \ n”。 然后你做下面的读取
cin >> a; // 1 cin >> b; // 2
在第一个之后,你的缓冲区将包含“\ nbar \ n”。 也就是说,换行符还在。第二个cin>>
首先会跳过所有的空格和换行符,这样它就可以应付\n
在前面bar
。 现在,您还可以对多个getline
调用进行sorting:
getline(cin, a); getline(cin, b);
Getline会抛弃它在行结尾处读取的\n
,但不会在开始时忽略换行符或空格。 所以,在第一个getline之后,缓冲区包含“bar \ n”。 第二个getline也会正确读取“bar \ n”。 现在,让我们考虑一下你需要清除/忽略的情况:
cin >> a; getline(cin, b);
第一个会将stream视为“\ nbar \ n”。 getline然后会立即看到\n
在开始,并会认为它读取一个空行。 因此,它会立即继续,而不是等待任何东西,留下的stream“bar \ n”。 所以,如果你在cin>>
之后有一个getline
,你应该先执行clear / ignore序列,清除换行符。 但是在getline
或cin>>
之间,你不应该这样做。
它是“卡住”,因为它正在等待input。 cin被附加到程序的标准input句柄上,你必须input一些东西然后回车。
cin >> ...
从标准input读取,直到find一个空格字符。 当你input8 5
的同义词列表, 8
被读入lineOfSyns
等等。 当程序到达cin >> addAntonymAnswer1
, 5
被读入addAntonymsAnswer1
。 你的程序意外行为,因为它期望yes
或no
但得到5
。
看看使用cin.getline()
而不是>>
。 例如,参见本页 18.2和18.3节。
在你的程序中你问用户:
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
然后,您尝试阅读input用户的行
cin>>lineOfSyns;
但是,这只能读取第一个空格。 所以当用户键入的第二个数字仍然在cin
缓冲区
cin>>addAntonymAnswer1;
行被执行,以便数据读入到addAntonymAnswer1
string中。 用户从来没有机会input“是”或“否”,并且对这些值的testing失败。
您应该考虑更改为使用getline()
的string
重载来进行读取:
getline( cin, stringvar);
这可能比使用cin.getline()
更好,因为它没有使用string
的重载 – 使用该成员函数,您需要读入一个字符数组,这比读入string
要灵活得多。