zzz2991
zzz2991

Reputation: 757

Purpose of if(cin)?

I'm here to ask for some help in understanding some concepts presented in accelerated c++. Here is where I am having a problem.

vector<Student_info> students;  //Student_info is a structure we made
Student_info record;
string::size_type maxlen = 0;


// read and store all the records, and find the length of the longest name
while (read(cin, record)) { //Here is where I find hard to follow
maxlen = max(maxlen, record.name.size());
students.push_back(record);
}

Definition of read():

istream& read(istream& is, Student_info& s)
{
// read and store the student's name and midterm and final exam grades
is >> s.name >> s.midterm >> s.final;
read_hw(is, s.homework); // read and store all the student's homework grades
return is;
}

definition of read_hw():

// read homework grades from an input stream into a vector<double>
istream& read_hw(istream& in, vector<double>& hw)
{
if (in) {
// get rid of previous contents
hw.clear() ;
// read homework grades
double x;
while (in >> x)
hw.push_back(x);
// clear the stream so that input will work for the next student
in.clear();
}
return in;
}

The way I understand it so far is that when we call: while (read(cin,record)) we ask for a string: record.name, and two double values: record.midterm and record.final. After our user has inputted that data, we will enter our read_hw() function where we will clear any previous elements that may have been in our vector. Then we input and record a a stream of values into a vector of homework grades called record.homework. I think I am understanding that much. If not, please let me know.

I don't understand how our function knows when to return in, and therefore return back to our first while loop. EDIT: Ah, the user has to make and end-of-file notification twice to end the program. So I suppose I answered my own question... But would someone be able to explain the purpose of if(in) in our read_hw() function, that would be very helpful. It would be if(cin), so does that wait for our user to input data? Or is if(cin) automatically true? (why?)

Upvotes: 0

Views: 228

Answers (1)

user3125280
user3125280

Reputation: 2829

No if(cin) doesn't wait - it checks for errors. Only the operator >> waits for input. In this case while(in >> x) does the reading and waiting. The reasons it is inside a while loop condition is because after in >> x finishes it returns a reference to in, which is implicitly converted to a bool, which is used to signal an error like if(cin).

In both cases, cin will be true if there has been no error, and false if there has been an error.

This gives a better idea of what is going on, but might be not be to welcoming. Basically whenever an istream is treated like a bool, it will be true is there was no error, and false if there has been an error.

Basically, the conversion of an istream (call it foo) to bool is always !foo.fail(). So it is the opposite of fail(). This means there are two ways it can be true (straight from the table here:

  1. Logical error on i/o operation (reading the wrong type, etc)
  2. Read/writing error on i/o operation (the unpredictable stuff)

So end of file isn't covered at all. That has to be checked with eof() or similar.

If an istream works out as false, you can distinguish between 1 and 2 using bad(). If bad is true it was case 2, if bad() is false, it will be case 1. (There are other ways as well, look at rdstate())

Upvotes: 3

Related Questions