На мой взгляд, лучшее решение этой проблемы - просто полностью ее избежать.
Вместо одной функции, которая пытается прочитать весь файл, я бы написал функцию, которая просто читает одну запись.Затем вызывайте эту функцию несколько раз, пока весь файл не будет прочитан.Чтобы соответствовать тому, как работает остальная часть стандартной библиотеки, функция для чтения одной записи должна называться operator>>
.Он должен получить ссылку istream
и ссылку на запись и вернуть ссылку на istream
, когда это будет сделано.
std::istream &operator>>(std::istream &is, gRec &record) {
is >> record.FirstName;
is >> record.LastName;
is >> record.NumSubjects;
for (int i=0; i<record.NumSubjects; i++) {
is >> record.subjects[i].code;
int raw_status;
is >> raw_status;
record.subject[i].status = cvt_status(raw_status);
is >> record.mark;
}
return is;
}
Лично я, вероятно, оттуда внесу пару изменений.Я бы сделал Status
, Subject
и Schedule
, каждый из которых определяет свой собственный operator>>
для чтения себя из файла:
class Status {
enum class status { enrolled, provisional, withdrawn } s;
friend std::istream &operator>>(std::istream &is, Status &s) {
int i;
is >> i;
switch (i) {
case 1: s.s = status::enrolled; break;
case 2: s.s = status::provisional; break;
case 3: s.s = status::withdrawn; break;
}
return is;
}
};
class Subject {
int code;
Status status;
int mark;
public:
friend std::istream &operator>>(std::istream &is, Subject &s) {
return is >> s.code >> s.status >> s.mark;
}
};
class Schedule {
std::vector<Subject> classes;
public:
friend std::istream &operator>>(std::istream &is) {
int num;
is >> num;
for (int i=0; i<num; i++) {
Subject temp;
is >> temp;
classes.push_back(temp);
}
return is;
}
};
Тогда запись будет выглядеть примерно так:
class Record {
std::string FirstName, LastName;
Schedule classes;
public:
std::istream &operator>>(std::istream &is, Record &r) {
return is >> r.FirstName >> r.LastName >> r.classes;
}
};
И, наконец, чтение всего файла, заполненного записями студентов, будет примерно таким:
std::ifstream infile("filename");
std::vector<Record> records{std::istream_iterator<Record>(infile), {}};