Reputation:
In the following simple code snippet, the end-of-file can be easily indicated by pressing ctrl-z
.
double x;
while ( cin >> x )
{
++count;
sum += x;
}
But when I try a more complicated program, such as reading in student records to do some processing, I fail to indicate the end-of-file to the program.
For example, I have a struct
object called Student_info
struct Student_info
{
string name;
double midterm, final;
vector<double> homework;
};
I have written several functions to read in and store several student records, as follows:
while ( read( cin, record ) )
{
students.push_back( record );
}
But after inputting a few student records, when I do ctrl-z
and hit the Enter to see the results, the command prompt is still waiting for me.
What am I doing wrong?
p.s.1. I separate names and grades with a blank space, and I separate students' details by jumping to the next line, which should be pretty much the same; i.e. some space separator. Right?
p.s.2. This code is adopted from the Accelerated C++ Book, and my knowledge of it is just up until Chapter 5 at the moment...
Thank you in advance,
EDIT
Below are two more functions that I use:
istream& read( istream& is, Student_info& s )
{
is >> s.name >> s.midterm >> s.final;
read_hw( is, s.homework );
return is;
}
istream& read_hw( istream& in, vector<double>& hw )
{
if ( in )
{
hw.clear();
double x;
while ( in >> x )
hw.push_back( x );
in.clear();
}
return in;
}
Upvotes: 3
Views: 927
Reputation: 61
when the cin read the EOF, it only set the instream flag eofbit and failbit. When you use
while(cin>>x)
,it implicit indicate a operator bool (std::cin),it return false when read EOF(the cin >> x return cin). Thus the while loop end.
But when you use
while ( read( cin, record ) )
the cin also return false when it read EOF,but your function read didn't recognize it.And when the while loop continue, the loop occur a new cin. And the important is the failbit flag will save in you stream until you use cin.clear().Thus your code is not good as overload operator >> for your student struct. I am sorry for my English,and hope you can clear.
Upvotes: 1
Reputation: 179819
The easiest solution would be to write an std::istream& operator>> ( std::istream& in, Student_info&)
which behaves similarly to the existing operator>>
. You can then use exactly the same loop:
Student_info record;
while ( cin >> record )
{
++count;
students.push_back( record );
}
Inside your operator>>
, you should just call operator>>
for all members, and then return the istream& in
argument.
Upvotes: 2