Introduction In this homework, you will create a C++ program to manage the list
ID: 3585494 • Letter: I
Question
Introduction In this homework, you will create a C++ program to manage the list of enrolled students in a university. The data of each student will be stored as nodes of an ordered linked list. You should be able to add and delete students from the list, and perform other operation on the stored data. Student information include: D number (integer of 5 digits) * .First name Last name .Major GPA (double, between 0 and 4) * .Current Credit Enrolled (integer, between 0 and 15) Input and Output The input is a single text file. Each file is divided in blocks that call different operations on the linked list, followed by the necessary arguments. The name used to declare the instruction to execute will be all in upper cases. Each new argument is in a new line of the file. Your program should go through the file and execute all the listed operations, and terminate when the end of file is reached. It is fair to assume that all calls will be in upper case letters and will always be separated by an empty line, even when the number of arguments is incorrect for the function call. The file terminates with new line and EOF Example 1 of input INSERT 03948 Tom Brady Physics 3.40 12 INSERT 03491 oe Flacco ChemistryExplanation / Answer
main.cpp
-----------------------------------------------
#include <string>
#include <sstream>
#include <fstream>
#include "ArgumentManager.h"
#include "OrderedLinkedList.h"
#include "Exception.h"
using namespace std;
void readFile(ifstream & infilename, ofstream& outfilename, OrderedLinkedList<nodeType<string>>& olList);
void readVariables(ifstream & infilename, string& idNum, string& firstName, string& lastName, string& major, string& gpa, string& credits, int b1, int b2, int b3, int b4, int b5, int b6);
int charCount(string& str);
bool checkGPA(string& GPA2);
bool checkCredits(string& credits);
bool checkMajor(string& major);
int main(int argc, char* argv[])
{
ArgumentManager am(argc, argv);
const string infilename = am.get("A");
const string outfilename = am.get("C");
ifstream infile{ infilename };
OrderedLinkedList<nodeType<string>> olList{};
ofstream outfile(outfilename);
readFile(infile, outfile, olList);
infile.close();
outfile.close();
}
void readFile(ifstream & infile, ofstream & outfile, OrderedLinkedList<nodeType<string>>& olList)
{
string line{ "" };
string idNum{ "0" };
string firstName{ "" };
string lastName{ "" };
string major{ "" };
string gpa{ "0.0" };
string credits{ "0" };
while (infile.good())
{
getline(infile, line);
if (line == "INSERT") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 1, 2, 3, 4, 5, 6);
olList.INSERT(nullptr, nullptr, idNum, firstName, lastName, major, gpa, credits);
}
else if (line == "PRINT_ROSTER")
{
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 1, 2, 3, 4, 5, 6);
olList.PRINT_ROSTER(outfile, infile);
}
else if (line == "PRINT_BY_MAJOR")
{
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 0, 0, 4, 0, 0);
olList.PRINT_BY_MAJOR(major, outfile, infile);
}
else if (line == "PRINT_BY_GPA") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 0, 0, 0, 5, 0);
olList.PRINT_BY_GPA(gpa, outfile, infile);
}
else if (line == "PRINT_STUDENT") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 2, 3, 0, 0, 0);
olList.PRINT_STUDENT(firstName, lastName, outfile, infile);
}
else if (line == "DELETE_STUDENT") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 2, 3, 0, 0, 0);
olList.DELETE_STUDENT(firstName, lastName);
}
else if (line == "DELETE_ID") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 1, 0, 0, 0, 0, 0);
olList.DELETE_ID(idNum);
}
else if (line == "UPDATE_GPA") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 2, 3, 0, 5, 0);
olList.UPDATE_GPA(firstName, lastName, gpa);
}
else if (line == "UPDATE_MAJOR") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 2, 3, 4, 0, 0);
olList.UPDATE_MAJOR(firstName, lastName, major);
}
else if (line == "ADD_CLASS") {
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 2, 3, 0, 0, 6);
olList.ADD_CLASS(firstName, lastName, credits);
}
else if (line == "REMOVE_CLASS")
{
readVariables(infile, idNum, firstName, lastName, major, gpa, credits, 0, 2, 3, 0, 0, 6);
olList.REMOVE_CLASS(firstName, lastName, credits);
}
else if (line == "GPA") {
olList.GPA(outfile);
}
}
}
void readVariables(ifstream & infile, string& idNum, string& firstName, string& lastName, string& major, string& gpa, string& credits, int b1, int b2, int b3, int b4, int b5, int b6)
{
while (infile.good())
{
string line2;
getline(infile, line2);
stringstream ss(line2);
if(b1 == 1)
{
try {
if (line2 == "")
throw Exception(line2);
if (charCount(line2) != 5)
throw(idNum);
ss >> idNum;
}catch(const string e)
{
idNum = "0";
cout << "Your ID: " << e << " is the incorrect number of digits. It must be 5 digits long" << endl;
}catch(Exception e)
{
idNum = "0";
cout << e.argMissing() << endl;
}
b1 -= 1;
}
else if (b2 == 2)
{
ss >> firstName;;
b2 -= 2;
}
else if (b3 == 3)
{
ss >> lastName;
b3 -= 3;
}
else if (b4 == 4)
{
try {
if (!checkMajor(major))
throw major;
if (line2 == "")
throw Exception(line2);
ss >> major;
}catch(Exception e){
major = "";
cout << e.argMissing() << endl;
}catch(string e)
{
major = "";
}
b4 -= 4;
}
else if (b5 == 5)
{
try
{
if (line2 == "")
throw Exception(line2);
if (!checkGPA(line2))
throw line2;
ss >> gpa;
}
catch (string e)
{
gpa = "0.00";
cout << "Your GPA: " << e << " is in the incorrect GPA format. Example: 3.58 or 0.00. It must be a number in between 0.00 and 4.00" << endl;
}catch(Exception e)
{
gpa = "0";
cout << e.argMissing() << endl;
}
b5 -= 5;
}
else if (b6 == 6)
{
try {
if (line2 == "")
throw Exception(line2);
if (!checkCredits(line2))
throw line2;
ss >> credits;
}catch(string e)
{
credits = "0";
cout << "Your credits: " << e << " is in the wrong format. It must be a whole number between 0 and 15." << endl;
}catch(Exception e)
{
credits = "0";
cout << e.argMissing() << endl;
break;
}
b6 -= 6;
}
if(line2 == "")
{
break;
}
ss.str("");
ss.clear();
}
}
int charCount(string& str)
{
int count{ 0 };
for(char i : str)
{
count++;
}
return count;
}
bool checkGPA(string& GPA2)
{
double gpaNum = stod(GPA2);
bool flag{ true };
int count{ 0 };
for(char i : GPA2)
{
if(i < 48 && i != 46 || i > 57)
{
flag = false;
}
count++;
}
if(GPA2[1] != '.')
{
flag = false;
}
if(gpaNum < 0.0 || gpaNum > 4.0)
{
flag = false;
}
return flag;
}
bool checkCredits(string& credits)
{
bool flag{ true };
int cr = stoi(credits);
if(cr < 0 || cr > 15)
{
flag = false;
}
return flag;
}
bool checkMajor(string & major)
{
bool flag = true;
for(char i : major)
{
if(i <65 || i > 90 && i < 97 || i > 122)
{
flag = false;
}
else
flag = true;
}
return flag;
}
---------------------------------------------------------------------------
OrderedLinkedList.h
----------------------------------------
#pragma once
#include <string>
#include "nodeType.h"
#include "linkedListType.h"
#include <iostream>
#include <iomanip>
using namespace std;
template<class Type>
class OrderedLinkedList : public linkedListType<Type>
{
private:
int count;
public:
OrderedLinkedList<Type>();
~OrderedLinkedList<Type>();
void INSERT(nodeType<string>* next,
nodeType<string>* previous, string idNum, string firstName,
string lastName, string major, string gpa, string credits);
void insertFirst(const Type& newItem);
void insertLast(const Type& newItem);
bool search(const Type& searchItem) const;
void deleteNode(const Type& deleteItem);
void PRINT_ROSTER(ofstream& outfile, ifstream& infile) const;
void PRINT_BY_MAJOR(string& major, ofstream& outfile, ifstream& infile);
void PRINT_BY_GPA(string& gpa, ofstream& outfile, ifstream& infile);
void PRINT_STUDENT(string& firstName, string& lastName, ofstream& outfile, ifstream& infile);
void DELETE_STUDENT(string& firstName, string& lastName);
void DELETE_ID(string& id);
void UPDATE_GPA(string& firstName, string& lastName, string& gpa);
void UPDATE_MAJOR(string& firstName, string& lastName, string& major);
void ADD_CLASS(string& firstName, string& lastName, string& credits);
void REMOVE_CLASS(string& firstName, string& lastName, string& credits);
void GPA(ofstream& outfile);
};
template <class Type>
OrderedLinkedList<Type>::OrderedLinkedList()
{
this->count = 0;
}
template<class Type>
inline OrderedLinkedList<Type>::~OrderedLinkedList()
{
this->destroyList();
}
template<class Type>
void OrderedLinkedList<Type>::INSERT(nodeType<string>* next,
nodeType<string>* previous, string idNum, string firstName,
string lastName, string major, string gpa, string credits)
{
nodeType<string> * node = new nodeType<string>
(nullptr, nullptr, idNum, firstName, lastName, major, gpa, credits);
count++;
if (this->isEmptyList()) {
node->next = this->last;
node->previous = this->first;
this->first = node;
this->last = node;
}
else if (!this->isEmptyList()){
nodeType<string>* reader = this->first;
while (reader && (lastName > reader->lastName || (lastName == reader->lastName && firstName > reader->firstName)))
{
reader = reader->next;
}
if(reader && reader->lastName == lastName)
{
if(reader->firstName == firstName || reader->idNum == idNum)
{
cout << "Duplicate entry. Input rejected." << endl;
delete node;
count--;
}
else
{
if(reader->firstName > firstName)
{
node->next = reader;
node->previous = reader->previous;
if (reader->previous != nullptr) {
reader->previous->next = node;
}
reader->previous = node;
if (this->first == reader)
{
this->first = node;
}
}
else
{
node->previous = reader;
node->next = reader->next;
if (reader->next != nullptr) {
reader->next->previous = node;
}
reader->next = node;
if(this->last == reader)
{
this->last = node;
}
}
}
}
else if(reader == nullptr)
{
node->next = nullptr;
node->previous = this->last;
this->last->next = node;
this->last = node;
}
else
{
node->next = reader;
node->previous = reader->previous;
if (reader->previous != nullptr){
reader->previous->next = node;
}
reader->previous = node;
if(this->first == reader)
{
this->first = node;
}
}
}
}
template<class Type>
void OrderedLinkedList<Type>::insertFirst(const Type& newItem)
{
}
template<class Type>
void OrderedLinkedList<Type>::insertLast(const Type& newItem)
{
}
template <class Type>
bool OrderedLinkedList<Type>::search(const Type& searchItem) const
{
return true;
}
template <class Type>
void OrderedLinkedList<Type>::deleteNode(const Type& deleteItem)
{
}
template<class Type>
void OrderedLinkedList<Type>::PRINT_ROSTER(ofstream& outfile, ifstream& infile) const
{
nodeType<string>* reader = this->first;
while(reader)
{
outfile << reader->firstName << " " << reader->lastName << ", " << reader->idNum << endl;
reader = reader->next;
}
if (!infile.eof())
{
outfile << endl;
}
}
template<class Type>
void OrderedLinkedList<Type>::PRINT_BY_MAJOR(string& major, ofstream& outfile, ifstream& infile)
{
nodeType<string>* reader = this->first;
while(reader)
{
if(reader->major == major)
{
outfile << reader->firstName << " " << reader->lastName << ", " << reader->idNum << endl;
}
reader = reader->next;
}
if (!infile.eof())
{
outfile << endl;
}
}
template<class Type>
void OrderedLinkedList<Type>::PRINT_BY_GPA(string& gpa, ofstream& outfile, ifstream& infile)
{
nodeType<string>* reader = this->first;
while (reader)
{
double GPA1 = stod(gpa);
double GPA2 = stod(reader->gpa);
if(GPA2 >= GPA1)
{
outfile << reader->firstName << " " << reader->lastName << ", " << reader->idNum << endl;
}
reader = reader->next;
}
if (!infile.eof())
{
outfile << endl;
}
}
template <class Type>
void OrderedLinkedList<Type>::PRINT_STUDENT(string& firstName, string& lastName, ofstream& outfile, ifstream& infile)
{
nodeType<string>* reader = this->first;
while(reader->lastName != lastName && reader->firstName != firstName)
{
reader = reader->next;
}
outfile << reader->firstName << " " << reader->lastName << ", " << reader->idNum << endl
<< "Major: " << reader->major << endl << "GPA: " << reader->gpa << endl << "Credits Enrolled: " << reader->credits << endl;
if(!infile.eof())
{
outfile << endl;
}
}
template<class Type>
void OrderedLinkedList<Type>::DELETE_STUDENT(string & firstName, string & lastName)
{
nodeType<string>* reader = this->first;
while(reader->lastName != lastName && reader->firstName != firstName)
{
reader = reader->next;
}
if (reader->previous != nullptr) {
reader->previous->next = reader->next;
}
else
{
this->first = reader->next;
}
if (reader->next != nullptr) {
reader->next->previous = reader->previous;
}
else
{
this->last = reader->previous;
}
delete reader;
}
template<class Type>
void OrderedLinkedList<Type>::DELETE_ID(string & id)
{
nodeType<string>* reader = this->first;
while (reader->idNum != id)
{
reader = reader->next;
}
if (reader->previous != nullptr) {
reader->previous->next = reader->next;
}
else
{
this->first = reader->next;
}
if (reader->next != nullptr) {
reader->next->previous = reader->previous;
}
else
{
this->last = reader->previous;
}
delete reader;
}
template<class Type>
void OrderedLinkedList<Type>::UPDATE_GPA(string & firstName, string & lastName, string& gpa)
{
nodeType<string>* reader = this->first;
while (reader->lastName != lastName && reader->firstName != firstName)
{
reader = reader->next;
}
reader->gpa = gpa;
}
template<class Type>
void OrderedLinkedList<Type>::UPDATE_MAJOR(string & firstName, string & lastName, string & major)
{
nodeType<string>* reader = this->first;
while (reader->lastName != lastName && reader->firstName != firstName)
{
reader = reader->next;
}
reader->major = major;
}
template<class Type>
void OrderedLinkedList<Type>::ADD_CLASS(string & firstName, string & lastName, string& credits)
{
nodeType<string>* reader = this->first;
while (reader->lastName != lastName && reader->firstName != firstName)
{
reader = reader->next;
}
const int cr1 = stoi(reader->credits);
const int cr2 = stoi(credits);
reader->credits = to_string(cr1 + cr2);
}
template<class Type>
void OrderedLinkedList<Type>::REMOVE_CLASS(string & firstName, string & lastName, string& credits)
{
nodeType<string>* reader = this->first;
while (reader->lastName != lastName && reader->firstName != firstName)
{
reader = reader->next;
}
const int cr1 = stoi(reader->credits);
const int cr2 = stoi(credits);
reader->credits = to_string(cr1 - cr2);
}
template<class Type>
void OrderedLinkedList<Type>::GPA(ofstream& outfile)
{
double total{ 0 };
nodeType<string>* reader = this->first;
while (reader)
{
total += stod(reader->gpa);
reader = reader->next;
}
const double mean = total / count;
outfile << setprecision(3) << "GPA mean: " << mean << setprecision(6) << endl << endl;
}
-------------------------------------------------------------------------------------
ArgumentManager.h
-------------------------------------------------
#ifndef ArgumentManager_h
#define ArgumentManager_h
#include <map>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
class ArgumentManager {
private:
map<string, string> m_argumentMap;
public:
ArgumentManager() { }
ArgumentManager(int argc, char *argv[], char delimiter=';');
ArgumentManager(string rawArguments, char delimiter=';');
void parse(int argc, char *argv[], char delimiter=';');
void parse(string rawArguments, char delimiter=';');
string get(string argumentName);
string toString();
friend ostream& operator << (ostream &out, ArgumentManager &am);
};
void ArgumentManager::parse(string rawArguments, char delimiter) {
stringstream currentArgumentName;
stringstream currentArgumentValue;
bool argumentNameFinished = false;
for (unsigned int i=0; i<=rawArguments.length(); i++) {
if (i == rawArguments.length() || rawArguments[i] == delimiter) {
if (currentArgumentName.str() != "") {
m_argumentMap[currentArgumentName.str()] = currentArgumentValue.str();
}
// reset
currentArgumentName.str("");
currentArgumentValue.str("");
argumentNameFinished = false;
}
else if (rawArguments[i] == '=') {
argumentNameFinished = true;
}
else {
if (argumentNameFinished) {
currentArgumentValue << rawArguments[i];
}
else {
if (rawArguments[i] == ' ')
continue;
currentArgumentName << rawArguments[i];
}
}
}
}
void ArgumentManager::parse(int argc, char *argv[], char delimiter) {
if (argc > 1) {
for (int i=1; i<argc; i++) {
parse(argv[i], delimiter);
}
}
}
ArgumentManager::ArgumentManager(int argc, char *argv[], char delimiter) {
parse(argc, argv, delimiter);
}
ArgumentManager::ArgumentManager(string rawArguments, char delimiter) {
parse(rawArguments, delimiter);
}
string ArgumentManager::get(string argumentName) {
map<string, string>::iterator iter = m_argumentMap.find(argumentName);
if (iter == m_argumentMap.end()) {
return "";
}
else {
return iter->second;
}
}
string ArgumentManager::toString() {
stringstream ss;
for (map<string, string>::iterator iter = m_argumentMap.begin(); iter != m_argumentMap.end(); iter++) {
ss << "Argument name: " << iter->first << endl;
ss << "Argument value: " << iter->second << endl;
}
return ss.str();
}
ostream& operator << (ostream &out, ArgumentManager &am) {
out << am.toString();
return out;
}
#endif
--------------------------------------------------------------------------------------------
Exception.h
----------------------------------------------------
#pragma once
#include<iostream>
using namespace std;
class Exception
{
private:
string argMessage{ "There are missing arguments." };
public:
Exception(string argMessage)
{
argMissing();
}
string argMissing()
{
return this->argMessage;
}
};
--------------------------------------------------------------------------------------------
linkedListIterator.h
--------------------------------------------
#pragma once
#include "nodeType.h"
template <class Type>
class linkedListIterator
{
public:
linkedListIterator();
linkedListIterator(nodeType<string> *ptr);
Type operator*();
linkedListIterator<Type> operator++();
bool operator==(const linkedListIterator<Type>& right) const;
bool operator!=(const linkedListIterator<Type>& right) const;
private:
nodeType<string> *current;
};
template <class Type>
linkedListIterator<Type>::linkedListIterator()
{
current = NULL;
}
template <class Type>
linkedListIterator<Type>::linkedListIterator(nodeType<string> *ptr)
{
current = ptr;
}
template <class Type>
Type linkedListIterator<Type>::operator*()
{
return current->info;
}
template <class Type>
linkedListIterator<Type> linkedListIterator<Type>::operator++()
{
current = current->link;
return *this;
}
template <class Type>
bool linkedListIterator<Type>::operator==
(const linkedListIterator<Type>& right) const
{
return (current == right.current);
}
template <class Type>
bool linkedListIterator<Type>::operator!=
(const linkedListIterator<Type>& right) const
{
return (current != right.current);
}
------------------------------------------------------------------------------------
linkedListType.h
-------------------------------------------
#pragma once
#include "linkedListIterator.h"
#include "nodeType.h"
template <class Type>
class linkedListType
{
public:
const linkedListType<Type>& operator=(const linkedListType<Type>&);
void initializeList();
bool isEmptyList() const;
void print() const;
int length() const;
void destroyList();
Type front() const;
Type back() const;
virtual bool search(const Type& searchItem) const = 0;
virtual void insertFirst(const Type& newItem) = 0;
virtual void insertLast(const Type& newItem) = 0;
virtual void deleteNode(const Type& deleteItem) = 0;
linkedListIterator<Type> begin();
linkedListIterator<Type> end();
linkedListType();
linkedListType(const linkedListType<Type>& otherList);
~linkedListType();
protected:
int count;
nodeType<string> *first;
nodeType<string> *last;
private:
void copyList(const linkedListType<Type>& otherList);
};
template <class Type>
bool linkedListType<Type>::isEmptyList() const
{
return (first == NULL);
}
template <class Type>
linkedListType<Type>::linkedListType() //default constructor
{
first = NULL;
last = NULL;
count = 0;
}
template <class Type>
void linkedListType<Type>::destroyList()
{
nodeType<string> *temp;
while (first != NULL)
{
temp = first;
first = first->next;
delete temp;
}
last = NULL;
count = 0;
}
template <class Type>
void linkedListType<Type>::initializeList()
{
destroyList();
template <class Type>
void linkedListType<Type>::print() const
{
nodeType<string> *current;
current = first;
while (current != NULL)
{
cout << current->info << " ";
current = current->next;
}
}
template <class Type>
int linkedListType<Type>::length() const
{
return count;
}
template <class Type>
Type linkedListType<Type>::front() const
{
///assert(first != NULL);
return first->info;
}
template <class Type>
Type linkedListType<Type>::back() const
{
return last->info;
}
template <class Type>
linkedListIterator<Type> linkedListType<Type>::begin()
{
linkedListIterator<Type> temp(first);
return temp;
}
template <class Type>
linkedListIterator<Type> linkedListType<Type>::end()
{
linkedListIterator<Type> temp(NULL);
return temp;
}
template <class Type>
void linkedListType<Type>::copyList
(const linkedListType<Type>& otherList)
{
nodeType<string> *newNode;
nodeType<string> *current;
if (first != NULL)
destroyList();
if (otherList.first == NULL)
{
first = NULL;
last = NULL;
count = 0;
}
else
{
current = otherList.first; /
count = otherList.count;
first = new nodeType<string>;
first->info = current->info;
first->next = NULL;
last = first;
current = current->next;
while (current != NULL)
{
newNode = new nodeType<string>;
newNode->info = current->info;
newNode->next = NULL;
last->next = newNode;
last = newNode;
current = current->next;
}
}
}
template <class Type>
linkedListType<Type>::~linkedListType()
{
destroyList();
}
template <class Type>
linkedListType<Type>::linkedListType
(const linkedListType<Type>& otherList)
{
first = NULL;
copyList(otherList);
}
template <class Type>
const linkedListType<Type>& linkedListType<Type>::operator=
(const linkedListType<Type>& otherList)
{
if (this != &otherList)
{
copyList(otherList);
}
return *this;
}
}
----------------------------------------------------------------------------------------
nodeType.h
---------------------------------------------------------
#pragma once
template <class Type>
struct nodeType
{
nodeType<Type> *next;
nodeType<Type> *previous;
Type idNum = 0;
Type firstName = "";
Type lastName = "";
Type major= "";
Type gpa = 0;
Type credits = 0;
Type info = "";
Type* link = nullptr;
Type gnu_dev_major = "";
nodeType<Type>() : idNum(0), firstName(""), lastName(""), major(""), gpa(0.0), credits(0){}
nodeType<Type>(nodeType<Type>* next,
nodeType<Type>* previous, Type idNum, Type firstName,
Type lastName, Type major, Type gpa, Type credits)
: next(nullptr), previous(nullptr), idNum(idNum), firstName(firstName),
lastName(lastName), major(major), gpa(gpa), credits(credits){}
};
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.