Reputation: 82
#include <iostream>
#include <vector>
using std::cin; using std::cout; using std::istream;
using std::vector; using std::endl;
struct Student_info {
std::string name;
double midterm;
double final;
std::vector<double> homework;
};
istream& read_hw(istream& in, vector<double>& hw)
{
if (in) {
hw.clear();
double x;
while (in >> x) {
cout << "double Grade from read_hw(): " << x << "\n";
hw.push_back(x);
}
in.clear();
}
return in;
}
istream& read(istream& is, Student_info& s)
{
is >> s.name >> s.midterm >> s.final;
std::cout << "string Name from read()" << s.name << std::endl;
read_hw(is, s.homework); // read and store all the student's homework grades
return is;
}
int main() {
Student_info s;
vector<double> hw;
while (read(cin, s)) {
cout << "String name from main()" << s.name << endl;
}
}
Example input/output: (I typed Jimbo 99 99 99 99, which printed as I expected. Then I typed Failure 5 5 5 5 5, which gave the result you see below.)
String name from main()Jimbo
string Name from read()lure
double Grade from read_hw(): 5
double Grade from read_hw(): 5
double Grade from read_hw(): 5
Failure 10 10 10 10 10 // new input.
String name from main()lure
string Name from read()lure
double Grade from read_hw(): 10
double Grade from read_hw(): 10
double Grade from read_hw(): 10
Jimbo 99 99 99 99 99 // new input again. note it prints Jimbo just fine.
String name from main()lure
string Name from read()Jimbo
double Grade from read_hw(): 99
double Grade from read_hw(): 99
double Grade from read_hw(): 99
I've tried searching already and all I got was stuff about ignore(), which I'm not using. I have a hunch this has to do with using while (cin >> x)
which is taking in doubles and then immediately switching to receiving strings with the next read()
loop.
Upvotes: 1
Views: 75
Reputation: 120031
You are getting this result because cin >> x
will not fail immediately upon seeing a letter. Some letters are permitted within numbers and number-like entities. Incidentally F, A, and I (either case) are among those (they appear within inf
and nan
strings which designate special floating point IEEE values). So cin >> x
will consume "Fai" and only then fail.
On the other hand, J is not such a letter, so upon seeing a J cin >> x
will fail immediately, leaving the letter in the stream for the next read.
Mitigation strategies include
Upvotes: 3