Hey man, if you have learned about functions you should consider splitting this code between some of them.
1. For example this should go inside 1 function that's responsible to get correct options input from the user
1 2 3 4 5 6 7 8 9 10 11
|
cout<<"Welcome to the class tracker!"<<endl;
cout<<"Choose an option."<<endl;
cout<<"1) Open a class from a file"<<endl;
cout<<"2) Add a new student"<<endl;
cout<<"3) Change existing student"<<endl;
cout<<"4) Delete a student"<<endl;
cout<<"5) Print a class list (includes the class average)"<<endl;
cout<<"6) Save the class to a file"<<endl;
cout<<"7) Quit"<<endl;
cin>>input;
cin.ignore();
|
2.
Open a class from a file
Looks like you have to open a file and read all the class members from it to some container representing a class (looks like in your case its
vector <Student> studentstructures;
). Its a good choice but you shouldn't be using it as a global variable :
http://stackoverflow.com/questions/484635/are-global-variables-bad
Also what if you want data about 2 classes to be at your fingertips at the same time to make comparisons or anything else. Now you have only 1 global variable where you can write into and read from. Consider making a function taking a
string
argument representing a filename and as return type choose
vector <Student>
representing class with its members. (
vector<Student> read_class_from_file(const string& filename)
)
When you are going to read class members from file and write them back to file you must overload
operator>>
and
operator<<
for
Student
because now there is no reading happening, you are just opening the file.
About #5
1 2 3 4 5 6 7 8 9 10 11
|
cout<<"Name | ID | Courses | Marks "<<endl;
cout<<"____________________________"<<endl;
for (int i=0; i<studentstructures.size(); i++)
{
cout<<studentstructures.at(i).name<<" "<<studentstructures.at(i).ID<<" ";
for(int l=0; l<studentstructures.at(l).numberCourses; l++)
{
cout<<studentstructures.at(l).coursetrack[l].coursename<<endl;
}
}
|
It compiles but you can easily get runtime exception thrown because of studentstructures.at(l)
and that's good because otherwise you would have undefined behavior.
Outer loop works fine but now when you go to inner loop your condition is
not dependent on outer loop at all
l<studentstructures.at(l).numberCourses;
that should be
i
from your outer loop. Think about what would happen to this condition when inner loop executes it body and increments l. The current studentstructures[i] from outer loop is not connected to inner loops studentstructures[l] in any way.
Same goes for your l in
cout<<studentstructures.at(l).coursetrack[l].coursename<<endl;
Also for inner loops condition use
studentstructures.at(i).coursetrack.size()
rather than numberCourses because vector itself knows better its own size than any other variable
To make it easier in C++11 you can write that inner loop like this
1 2
|
for(const auto& c : studentstructures.at(i).coursetrack)
cout<<c<<endl;
|
You should be using different character than l for inner loop because i and l are as confusing to look at as O and 0 next to each other and its only matter of time when typing errors as yours happens.
Consider making #5 a function as well with signature something like this
void print_class_vector(const vector<Student>& class_vec)