0

So I have this code where an object of class Group has vector with objects from class Student. I am already writing information about the students from the vector into a file but I have problem with reading this information back. How can I do that?

Here is my code so far:

class Group { private: string name; vector <Student*> studentList; public: ~Group(); Group(void); Group(string s); void addStudent(string name,int age,int stNum); void removeStudent(int stNum); friend ostream& operator << (std::ostream& out, const Group& g) { out << g.name << "\n"; out << g.studentList.size() << "\n"; for (unsigned i=0;i<g.studentList.size();i++) { out<< g.studentList[i]->getStudentName()<<"\n"; out<< g.studentList[i]->getStudentAge()<<"\n"; out<< g.studentList[i]->getStudentNumber()<<"\n"<<endl; } return out; } friend istream& operator>>(std::istream& in, Group& g){ in >> g.name; for (unsigned i=0;i<g.studentList.size();i++) { //READ DATA FROM FILE } return in; } }; 
11
  • what is the format of the file data? also read en.cppreference.com/w/cpp/io/basic_ifstream Commented Dec 9, 2019 at 22:59
  • It is a .txt file Commented Dec 9, 2019 at 23:00
  • Looks like you write the file line by line. Consider using std::getline to do the reverse. Commented Dec 9, 2019 at 23:00
  • 1
    Side note: std::vector is at it's absolute best when it contains things directly rather than pointing to them. There is far less memory management involved and since the data is stored contiguously in the vector, there can be orders of magnitude performance improvements. Commented Dec 9, 2019 at 23:06
  • 1
    in >> *g.studentList[i], but first you would likely have to new a Student for the pointer to point at. You probably don't want to have to put up with crap like that, though. See above comment. I would ditch pointers entirely and Student temp; while (in >> temp) g.studentList.push_back(temp); Commented Dec 9, 2019 at 23:08

1 Answer 1

1

Gathering up the commentary. Note this pushes the hard part, the reading and writing, into Student and I left that bit blank. Normally I'd do it because I'm evil, but apparently in this case it is already written.

Major changes:

  • No Student pointers. Lest memory management overhead and better cache friendliness! By Grabthar's hammer. What a savings.
  • Student does the Student reading and writing.
  • std::vector handles the element counting so it doesn't need to be stored in and read from the output. Note: This could slow the reading down a little because you can't pre-allocate storage in the vector.
#include <string> #include <iostream> #include <vector> // note the lack of using namespace std; // it can be problematic, and especially so in a header. class Student { //fill in the blanks friend std::ostream& operator <<(std::ostream& out, const Student& s) { //fill in the blanks return out; } friend std::istream& operator >>(std::istream& in, const Student& s) { //fill in the blanks return in; } }; class Group { private: std::string name; std::vector<Student> studentList; // death to pointers! public: //~Group(); // Don't need a destructor without the pointer Group(void); Group(std::string s); void addStudent(std::string name, int age, int stNum); void removeStudent(int stNum); friend std::ostream& operator <<(std::ostream& out, const Group& g) { out << g.name << "\n"; //out << g.studentList.size() << "\n"; not necessary. vector handles it. for (std::vector<Student>::const_iterator it = g.studentList.cbegin(); it != g.studentList.cend(); ++it) { if (!(out << *it))// let Student's << do all the work { // write failed. Might as well stop trying to write. break; } } return out; } friend std::istream& operator>>(std::istream& in, Group& g) { in >> g.name; Student temp; while (in >> temp) // let Student's >> do all the work { g.studentList.push_back(temp); } return in; } }; 
Sign up to request clarification or add additional context in comments.

8 Comments

Is the for loop from c++11? I get it as a warning. I should not use anything from c++11 Also, now it is crashes when I try to save the group. Before it did not.
That's a C++11 for loop. Gimme a second and I'll remove it.
If it crashes on save there is likely something wrong in the Student << overload or the pointer is still in play.
Well, now when not using the c++11 for loop it works.
This is the same as for (int index = 0; index < g.studentList.size(); ++index) { if (!(out << g.studentList[index]) { break; } }
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.