#include #include #include using namespace std; /* Да се дефинира клас, поддържащ множество от студенти в двоичен файл с пряк достъп. Класът да позволява: * добавяне на студент във файла * търсене по ФН * изтриване * отпечатване на всички студенти */ struct Student { public: int fn; char name[256]; Student (){}; Student (int _fn, char *_name):fn(_fn) { strcpy (name,_name); } }; struct StudentRecord { bool validRecord; Student data; }; class StudentsList { public: StudentsList (char *fileName) { file.open (fileName,ios::binary | ios::in | ios::out); if (!file) { forceCreate (fileName); file.open (fileName,ios::binary | ios::in | ios::out); } cacheCount = -1; cachedIndex = -1; } //търсене на студент по ФН Student operator () (int fn) {Student empty; return empty;}; //редакция на студент - променя данните за студента със същия ФН void setStudent (const Student&); //добавяне на студент void addStudent (const Student&); //изтриване на студент void eraseStudent (int fn){}; int count (); friend ostream& operator << (ostream&,StudentsList&); ~ StudentsList () { //нямя нужда да затваряме файла деструкторът на fstream ще го напрвави } private: fstream file; //когато cacheCount == -1, размерът е неизвестен. int cacheCount; //индекс на последния прочетен от файла запис (-1 - няма) int cachedIndex; StudentRecord cachedRecord; //търсене на студент по индекс StudentRecord& operator [] (int index); void forceCreate (char* fname) { ofstream f (fname,ios::binary); } }; void StudentsList::setStudent (const Student& st) { //търсим позицията на студента във файла int i= 0; while (i < count () && (*this)[i].data.fn != st.fn) i++; if (i < count ()) { StudentRecord record; record.data = st; record.validRecord = true; file.seekp (i*sizeof(StudentRecord)); file.write ((char*)&st,sizeof (StudentRecord)); } else { addStudent (st); } cachedIndex = -1; } void StudentsList::addStudent (const Student& st) { int i = 0; while (i < count () && (*this)[i].validRecord) i++; StudentRecord record; record.data = st; record.validRecord = true; assert (file.good()); file.seekp (i*sizeof(StudentRecord)); file.write ((char*)&record,sizeof (StudentRecord)); cacheCount = -1; cachedIndex = -1; } int StudentsList::count () { if (cacheCount != -1) return cacheCount; file.flush (); file.seekg (0,ios::end); cacheCount = file.tellg () / sizeof (StudentRecord); return cacheCount; } ostream& operator << (ostream& out, StudentsList& list) { for (int i = 0; i < list.count (); i++) { if (list[i].validRecord) out << list[i].data.fn << " " << list[i].data.name << endl; } return out; } StudentRecord& StudentsList::operator [] (int index) { if (cachedIndex == index) return cachedRecord; file.flush(); file.seekg (index*sizeof (StudentRecord)); file.read ((char*)&cachedRecord,sizeof (StudentRecord)); return cachedRecord; } void main () { StudentsList list ("students.dat"); Student st (100,"Test Student"); list.addStudent (st); cout << list.count() << endl; cout << list; }