Вы не можете сделать необработанный read
из файла в People
объект. People
содержит нетривиальный тип (std::string
), и каждая запись в файле должна иметь одинаковый размер для работы необработанных операций чтения, что не имеет место в вашем файле.
Что люди часто добавляют перегрузку для operator>>
для поддержки форматированного ввода из любого std::istream
(например, std::ifstream
или std::cin
).
Поскольку переменные-члены private
, вам необходимо добавьте operator>>
a friend
, чтобы он мог обращаться к переменным private
.
Вы можете использовать std::getline
для чтения, пока не будет найден определенный символ (например, ваш разделитель -
). Он удалит разделитель из потока, но не включит его в переменную, в которой хранится результат.
std::getline
возвращает ссылку на istream
, из которого было дано чтение, чтобы вы могли связать несколько std::getline
s.
Я бы также переименовал ваш класс в Person
, поскольку он содержит информацию только об одном человеке.
Пример:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
class Person {
std::string name;
std::string occupation;
int cats_age[2];
int age;
friend std::istream& operator>>(std::istream&, Person&);
friend std::ostream& operator<<(std::ostream&, const Person&);
};
// read one Person from an istream
std::istream& operator>>(std::istream& is, Person& p) {
using std::getline;
char del; // for reading the delimiter '-'
std::string nl_eater; // for removing the newline after age
// chaining getline:s and >>:s
return getline(getline(getline(is, p.name, '-'), p.occupation, '-') >>
p.cats_age[0] >> del >> p.cats_age[1] >> del >> p.age, nl_eater);
}
// write one Person to an ostream
std::ostream& operator<<(std::ostream& os, const Person& p) {
return os << p.name << '-' << p.occupation << '-' << p.cats_age[0] << '-'
<< p.cats_age[1] << '-' << p.age << '\n';
}
int main() {
// example of an istream - it could just as well had been a std::ifstream
std::istringstream is(
"marry wang-dog walker-0-17-78\n"
"foo bar-unemployed-1-2-3\n"
);
std::vector<Person> people;
Person temp;
while(is >> temp) { // loop for as long as extraction of one Person succeeds
people.push_back(temp);
}
// print all the collected Persons
for(const Person& p : people) {
std::cout << p;
}
}
Вывод:
marry wang-dog walker-0-17-78
foo bar-unemployed-1-2-3
Я предлагаю выбрать другой разделитель полей, чем -
. Многие имена содержат -
, как и отрицательные числа. Используйте символ, который вряд ли будет включен ни в одно из полей.