Checking For Missing Input

I made this before, but an error with the site, so :/

My problem is really basic, but for the life of me I can't do it. Basically, it's from Stroustrup's beginner book, the final leg of the Chapter 15 exercise. It asks:

"Change the representation of Person to have first_name and second_name instead of name. Make it an error not to
supply both a first and a second name. Be sure to fix >> and << also. Test."

Now, everything is fine with the program assuming it gets good input (meaning everything is definitely not fine, but it DOES work when used properly). I would explain it, but code probably does it better:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//pretend the preprocessor directives are there, because they are...
struct Person {
	Person(string f, string l, int a) :first{ f }, last{ l }, age{ a }
	{
		for (int i = 0; i < f.size(); ++i) {
			if (!isalpha(f[i])) error("Invalid character ", f[i]);
		}
		for (int i = 0; i < l.size(); ++i) {
			if (!isalpha(l[i])) error("Invalid character ", l[i]);
		}
		if (!(a >= 0 && a < 150)) error("Invalid age ", a);
	}
	Person() {}

	string get_first() const { return first; }
	string get_last() const { return last; }
	int get_age() const { return age; }
private:
	string first;
	string last;
	int age;
};


istream& operator >> (istream& is, Person& p)
{
	string f;
	string l;
	int a;
	is >> f >> l >> a;
	if (!is) return is;
	//NOTE FOR C++ FORUM READERS -- doesn't solve the problem.
	if (f == " " || l == " ") error("Missing name parameter");
	return is;
}
//pretend there is an ostream operator<<, because there is...
int main()
try
{
	using namespace Graph_lib; //ignore -- irrelevant

	string peoplegood = "Raul Rodriguez 68 Peter Smith 20 Doug Funny 14 Lily Whatever 89";
	string peoplebad = "Raul 68 Peter Smith 20 Doug Funny 14 Lily Whatever 89";
	istringstream iss{ peoplebad };

	cout << "Person:\n";
	Person p;
	vector<Person>vp;
	while (iss >> p)
	{
		vp.push_back(p);
	}

	for (const Person& p : vp) {
		cout << '\t' << p << endl;
	}
}
//pretend it has exception handlers, because it does... 


I'm just not sure how to do it. I wanted to use a stringstream because I understand cin well enough, but I'm iffy on stringstreams and wanted practice. I'm not sure if I should be dealing with it in the operator>>, the constructor, or the actual while loop. If I put good data in (using the good string to stringstream) it works fine, but if I don't, it just sits there saying, "Person" and not giving the error I'd like. I looked at user code online for it, and I'm not seeing it there either, unfortunately.
Last edited on
Also, while I have you FABULOUS people here (shamelessly pandering to people that know far more about this than I), may I also ask:

How can I include an operator in a class as a member? Or possibly a better question: SHOULD I do this? Taking the above as an example:

1
2
3
4
5
6
struct Person{
//implementation details
ostream& operator<<(ostream&);
//alternatively, which I didn't think I would need since it's in the class as a member
ostream& operator<<(ostream&, const Person&);
}

I get some strange errors related to everything from, "too many parameters" to, "unresolved external" yadda yadda. I never had a problem defining them as free functions outside the classes (and in fact was the only method I utilized before) but figured, "What better time to learn?" But as you can see, it's not going well.
Topic archived. No new replies allowed.