// Program: classlist
// File: classlist_vec.cpp
// Author: Chuck Stewart
// Purpose: Build and maintain a list of students enrolled in a class and a waiting list.
// Initially it uses vectors, but we will change it to use iterators, and then lists.
#include
#include
#include
#include
#include
using namespace std;
void enroll_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting);
void remove_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting);
void erase_from_vector(unsigned int i, vector& v);
int main() {
// Read in the maximum number of students in the course
unsigned int max_students;
cout << "\nWelcome to the enrollment program for CSCI 1200\n"
<< "Please enter the maximum number of students allowed\n";
cin >> max_students;
// Initialize the vector
vector enrolled;
vector waiting;
// Invariant:
// (1) enrolled contains the students already in the course,
// (2) waiting contains students who would will to be admitted (in
// the order of request) if a spot opens up, in the
// (3) enrolled.size() <= max_students,
// (4) if the course is not filled (enrolled.size() != max_students)
// then waiting is empty
do {
// check (part of) the invariant
assert (enrolled.size() <= max_students);
assert (enrolled.size() == max_students || waiting.size() == 0);
cout << "\nOptions:\n"
<< " To enroll a student type 0\n"
<< " To remove a student type 1\n"
<< " To end type 2\n"
<< "Type option ==> ";
int option;
if (!(cin >> option)) {
// if we can't read the input integer, then just fail.
cout << "Illegal input. Good-bye.\n";
return 1;
} else if (option == 2) {
// quit by breaking out of the loop.
break;
} else if (option != 0 && option != 1) {
cout << "Invalid option. Try again.\n";
} else { // option is 0 or 1
string id_number;
cout << "Enter student id: ";
if (!(cin >> id_number)) {
cout << "Illegal input. Good-bye.\n";
return 1;
} else if (option == 0) {
enroll_student(id_number, max_students, enrolled, waiting);
} else {
remove_student(id_number, max_students, enrolled, waiting);
}
}
}
while (true);
// some nice output
sort(enrolled.begin(), enrolled.end());
cout << "\nAt the end of the enrollment period, the following students\n"
<< "are in the class:\n\n";
for (unsigned int i=0; i& enrolled, vector& waiting) {
// Check to see if the student is already enrolled. If so, output a
// message and return.
unsigned int i;
for (i=0; i < enrolled.size(); ++i) {
if (enrolled[ i ] == id_number) {
cout << "Student " << id_number << " is already enrolled." << endl;
return;
}
}
// If the course isn't full, add the student. Then return.
if (enrolled.size() < max_students) {
enrolled.push_back(id_number);
cout << "Student " << id_number << " added.\n" << enrolled.size()
<< " students are now in the course." << endl;
return;
}
// Otherwise, we have to deal with the waiting list. Check to see
// if the student is already on the waiting list.
for (i=0; i < waiting.size(); ++i) {
if (waiting[ i ] == id_number) {
cout << "Student " << id_number << " is already on the waiting list." << endl;
return;
}
}
// Otherwise, add the student to the waiting list.
waiting.push_back(id_number);
cout << "The course is full. Student " << id_number
<< " has been added to the waiting list.\n" << waiting.size()
<< " students are on the waiting list." << endl;
}
// Remove a student from the course or from the waiting list. If
// removing the student from the course opens up a slot, then the
// first person on the waiting list is placed in the course.
void remove_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting) {
// Check to see if the student is on the course list.
bool found = false;
unsigned int loc=0;
while (!found && loc < enrolled.size()) {
found = enrolled[ loc ] == id_number;
if (!found) ++ loc;
}
// If so, remove the student and see if a student can be taken from the waiting list.
if (found) {
erase_from_vector(loc, enrolled);
cout << "Student " << id_number << " removed from the course." << endl;
if (waiting.size() > 0) {
enrolled.push_back(waiting[ 0 ]);
cout << "Student " << waiting[ 0 ] << " added to the course "
<< "from the waiting list." << endl;
erase_from_vector(0, waiting);
cout << waiting.size() << " students remain on the waiting list." << endl;
} else {
cout << enrolled.size() << " students are now in the course." << endl;
}
} else {
// If not, check to see if the student is on the waiting list
found = false;
loc = 0;
while (!found && loc < waiting.size()) {
found = waiting[ loc ] == id_number;
if (! found) ++ loc;
}
if (found) {
erase_from_vector(loc, waiting);
cout << "Student " << id_number << " removed from the waiting list.\n"
<< waiting.size() << " students remain on the waiting list." << endl;
} else {
cout << "Student " << id_number
<< " is in neither the course nor the waiting list" << endl;
}
}
}
// Remove the value at index location i from a vector of strings. The
// size of the vector should be reduced by one when the function is finished.
void erase_from_vector(unsigned int i, vector& v) {
assert (i >= 0);
assert (v.size() > 0);
assert (i < v.size());
int old_size = v.size();
// shift everything forward
for (int index = i; index < v.size()-1; index++) {
v[index] = v[index+1];
}
// shorten the vector by 1
v.pop_back();
assert (v.size() == old_size - 1);
}