C++ ifstream failure, why is this line not going where it's supposed to?
Question
I want to make the line marked with // THIS LINE SHOULD BE PRINTING do its thing, which is print the int values between "synonyms" and "antonyms".
This is the text file:
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
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
class WordInfo{
public:
WordInfo(){}
~WordInfo() {
}
int id() const {return myId;}
void readWords(istream &in)
{
in>>myId>>word;
}
void pushSynonyms (string synline, vector <WordInfo> wordInfoVector)
{
stringstream synstream(synline);
vector<int> synsAux;
int num;
while (synstream >> num) synsAux.push_back(num);
for (int i=0; i<synsAux.size(); i++){
cout<<synsAux[i]<<endl; //THIS LINE SHOULD BE PRINTING
}
}
void pushAntonyms (string antline, vector <WordInfo> wordInfoVector)
{
}
//--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;}
private:
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: ";
getline (cin,wordFile);
ifstream inStream (wordFile.data());
if(!inStream.is_open())
{
cerr<<"cannot open "<<wordFile<<endl;
exit(1);
}
vector <WordInfo> wordVector;
WordInfo aword;
while (inStream >>aword && (!(aword=="synonyms")))
{
wordVector.push_back(aword);
}
int i=0;
while (i<wordVector.size()){
cout<<wordVector[i]<<endl;
i++;
}
vector <int> intVector;
string aLine; //suspect
// bad statement?
while (getline(inStream, aLine)&&(aLine!=("antonyms"))){
aword.pushSynonyms(aLine, wordVector);
}
system("PAUSE");
return 0;
}
Solution
The problem seems to be here:
in>>myId>>word;
On the "synonyms" line the extraction of myId
fails and sets failbit
on the stream, which causes the following extractions to also fail. You have to reset the error control state before extracting further elements (like the word "synonyms") from the stream:
in.clear();
OTHER TIPS
First, turn on compiler warnings. It may help you find some things that you think are OK but which really aren't. For example, functions with non-void
return types should always return something. If they don't, then your program's behavior is undefined, and undefined behavior includes "working exactly as you wanted, except for some subtle difference later in the program." If you're using g++, the option for warnings is -Wall
.
Second, note that it's not just the highlighted line that isn't running. The entire pushSynonyms
function never gets called. Has your class covered how to use the debugger yet? If so, then consider using it. If not, then try putting some "cout
" statements in your program so you can see exactly how far your program gets before it goes wrong.
Third, note that when a stream read failure occurs, the stream's fail bit is set. Until you clear it (as shown by sth's answer), no further extraction can occur from that stream, so all further uses of >>
and getline
will fail.
Have you done any diagnostic printing? For example, what is synsAux.size()
? Have you checked what is in synline
before you start processing it? Have you checked which numbers are collected from the input stream?