Reputation: 67
So the while loop at the bottom of this following code simply just loops continuously I had it working before I added the line
questionFile >> answersArray[i];
This line seems to break it so that nothing writes into the questionsArray anymore, I'm rather stumped by this so help would be appreciated.
ifstream questionFile;
int i = 0;
switch (x){
case 1:
questionFile.open("Topic1 Questions.txt", ios::app);
break;
case 2:
questionFile.open("Topic2 Questions.txt", ios::app);
break;
case 3:
questionFile.open("Topic3 Questions.txt", ios::app);
break;
case 4:
questionFile.open("Topic4 Questions.txt", ios::app);
break;
}
if (!questionFile)
{
cout << "Cannot load file" << endl;
}
else
{
if (questionFile.peek() != ifstream::traits_type::eof()) {
while (!questionFile.eof())
{
getline(questionFile, questionsArray[i]);
questionFile >> answersArray[i];
i++;
}
}
questionFile.close();
}
Upvotes: 0
Views: 257
Reputation: 442
Both getline
and operator>>
extract from the file but getline
reads until '\n' (or any character you specify) while operator>>
reads until a whitespace. Furthermore, operator>>
will leave the '\n' in the stream causes the next invocation of getline
to read nothing.
Read the getline
and operator>>
documentations for more details (those are links).
Also, post the format that the questions/answers are stored in the file because how your code will run is very dependent on that. If you're just expecting alternating lines of questions and answers, just use getline
and forget the operator.
Hopefully this helps.
Upvotes: 1
Reputation: 490048
It's a little hard (okay, impossible, really) to be certain what your problem is without seeing things like the type of answersArray
. It would also help (a lot) to see what a sample of the input file you want to read.
For the moment, I'm assuming your input file look at least a little like this:
1) air 2) earth 3) fire 4) water
3
1) Solid 2) Liquid 3) Gas 4) Plasma
2
i.e., one line is a string (containing questions or possible answers, or maybe both), and the next line is a single number signifying the correct answer (or something on that order).
Assuming that's the case, I'd read all the data from the input file itself using std::getline
. Then I'd split that up into the necessary pieces.
I'd probably also create an answer
class (or something similar) to hold both the string and the number, and overload operator>>
for that class to read both.
struct answer {
std::string question;
int answer;
friend std::istream &operator>>(std::istream &is, answer &a) {
std::getline(is, a.question);
std::string temp;
std::getline(is, temp);
a.answer = boost::lexical_cast<int>(temp);
return is;
}
};
Using that, reading the data from the file could look something like this:
std::vector<answer> answers{
std::istream_iterator<question>(questionFile),
std::istream_iterator<question>()};
This reads the data from the file, and puts the items it reads into the vector I've named answers
.
While we're at it, I'd also change the code to open the file, at least a little bit. ios::app
only really makes sense if you're going to write to a file, not just read from it. Second, a case statement to choose hard-coded file names seems a bit clumsy, at least to me.
I'd probably write that part of the code more like this:
if (x<0 || x > 4)
throw std::runtime_error("prohibited file name");
std::stringstream name << "Topic" << x << " Questions.txt";
std::ifstream questionFile(name.str());
Upvotes: 0