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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Osman Zakir
// 6 / 23 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 15 Class definition drill
// Drill Specifications:
/**
* 1. Define a struct Person containing a string name and an int age.
* 2. Define a variable of type Person , initialize it with “Goofy” and 63, and
* write it to the screen ( cout ).
* 3. Define an input ( >> ) and an output ( << ) operator for Person ; read in a
* Person from the keyboard ( cin ) and write it out to the screen ( cout ).
* 4. Give Person a constructor initializing name and age .
* 5. Make the representation of Person private, and provide const member
* functions name() and age() to read the name and age.
* 6. Modify >> and << to work with the redefined Person .
* 7. Modify the constructor to check that age is [0:150) and that name doesn’t
* contain any of the characters ; : " ' [ ] * & ^ % $ # @ ! . Use error() in case
* of error. Test.
* 8. Read a sequence of Person s from input ( cin ) into a vector<Person> ;
* write them out again to the screen ( cout ). Test with correct and errone-
* ous input.
* 9. 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.
*/
#include "../../cust_std_lib_facilities.h"
#include <iostream>
#include <vector>
#include <string>
struct Person
{
Person(const std::string &name, const int age);
Person();
std::string name() const { return m_name; }
int age() const { return m_age; }
void set_name(const std::string &name) { m_name = name; }
void set_age(const int age) { m_age = age; }
private:
std::string m_name;
int m_age;
};
std::ostream &operator<<(std::ostream &os, const Person &person);
std::istream &operator>>(std::istream &is, Person &person);
void fill_person_v(std::vector<Person> &persons_v);
void print_person_v(const std::vector<Person> &persons_v);
int main()
{
using namespace std;
try
{
vector<Person> persons_v;
fill_person_v(persons_v);
print_person_v(persons_v);
}
catch (const runtime_error &rte)
{
cerr << "Runtime error: " << rte.what() << '\n';
}
catch (const out_of_range &oor)
{
cerr << "Out of range error: " << oor.what() << '\n';
}
keep_window_open();
}
Person::Person(const std::string &name, const int age)
:m_name{ name }, m_age{ age }
{
if (age < 0 || age > 150)
{
error("age out of range");
}
std::string bad_chars{ ":;''""[]*&^%$#@!" };
for (std::size_t i = 0; i < m_name.size(); ++i)
{
if (m_name.find_first_of(bad_chars[i]))
{
error("name consists of invalid characters");
}
}
}
Person::Person()
: m_name{}, m_age{}
{
}
std::ostream &operator<<(std::ostream &os, const Person &person)
{
return os << person.name() << " -- age: " << person.age();
}
std::istream &operator>>(std::istream &is, Person &person)
{
using namespace std;
string name;
getline(is, name, '\n');
int age;
is >> age;
person = Person::Person{ name, age };
return is;
}
void fill_person_v(std::vector<Person> &persons_v)
{
using namespace std;
cout << "Enter some people's name and age (separate name and age by 'Enter' keypress, please)\n"
<< "end sequence of persons by entering '~'\n";
for (Person person; cin >> person;)
{
char ch;
cin.get(ch);
if (ch != '~')
{
cin.putback(ch);
persons_v.push_back(person);
}
else
{
cout << "Sequence ended\n";
break;
}
}
}
void print_person_v(const std::vector<Person> &persons_v)
{
using namespace std;
for (std::size_t i = 0; i < persons_v.size(); ++i)
{
cout << persons_v.at(i) << '\n';
}
}
|