Re: Differences in reading from an istream vs. stringstream
David Crow wrote:
Given the following input file:
bob 1 2 3 4 5
mary 2 3 4 5 6 7
susan 3 4 5 6 7 8 9
This code snippet does not read it correctly:
class Student
{
public:
...
private:
std::string _Name;
std::vector<int> _Grades;
};
...
/***** this only gets called once *****/
std::istream& operator>>(std::istream& is, Student& s)
{
string name = "";
^^^^^ why? Don't you trust constructors?
is >> name;
std::vector<int> grades;
std::copy(std::istream_iterator<int>(is),
std::istream_iterator<int>(), std::back_inserter(grades));
/***** at this point, name and the grades vector are correct for the
'first' line in the input file *****/
Initialize the vector with the istream_iterators. Note that that is subject
to the "most vexing parse in C++".
Anyway, this code will read until an operation fails, just as Igor already
said. However, it is not the badbit which gets set but the failbit.
If you want one record per line, first read a line (with getline( in, line))
and then use a stringstream to parse it.
std::istream& operator>>(std::istream& is, Student& s)
{
std::string name = "";
is >> name;
std::string sGrades = "";
std::getline(is, sGrades);
std::stringstream ss(sGrades);
std::vector<int> grades;
std::copy(std::istream_iterator<int>(ss),
std::istream_iterator<int>(), std::back_inserter(grades));
s.setName(name);
s.setGrades(grades);
return is;
}
Yep, like that, but of course you still have to do all the error-checking.
Uli