In this project you will:
A person's daily schedule can include many different things. Additionally, the desire to change a persons schedule is also important.
For this project, there will be items that are specific things that a person has to do. For example, an item might be "Wake up at 8am". The schedule will allow the user to insert items where they will be inserted where they should be based on their time. There is a third class called manager that manages one or more schedules.
Your assignment is to build an application that will allow the user to create multiple schedules.
Initially, you will have to use the following files Item.h, Schedule.h, Manager.h, makefile, proj3.cpp, and three input files (proj3_schedule1.txt, proj3_schedule2.txt, and proj3_ schedule3.txt).
A normal run of the compiled code would look like this with user input highlighted in blue:
elon@linux2 proj3]$ make val1
valgrind ./proj3 proj3_schedule1.txt
==193428== Memcheck, a memory error detector
==193428== Copyright (C) 2002-2017, and GNU GPL'd, by Julian
Seward et al.
==193428== Using Valgrind-3.17.0 and LibVEX; rerun with -h for
copyright info
==193428== Command: ./proj3 proj3_schedule1.txt
==193428==
***Manager***
Opened File
18 nodes loaded across 1 schedules.
What would you like to do?:
1. Display Schedules
2. Reverse Schedules
3. Insert New Item
4. Exit
1
Schedule for 1
18 activities scheduled
800 : Wake up
815 : Coffee
830 : Gym
915 : Shower and breakfast
1015 : Travel to class
1030 : Class 1
1145 : Travel to Lunch
1200 : Lunch and hang with friends
1300 : Class 2
1415 : Travel to class
1430 : Class 3
1545 : Travel home
1600 : Homework and studying
1800 : Dinner with friends
1900 : Hang with friends
2000 : Homework and studying
2200 : Games, friends, and parties
2400 : Sleep
What would you like to do?:
1. Display Schedules
2. Reverse Schedules
3. Insert New Item
4. Exit
Here is a longer example run where there are three different schedules in the input file.
[elon@linux2 proj3]$ make run2
./proj3 proj3_schedule2.txt
***Manager***
Opened File
54 nodes loaded across 3 schedules.
What would you like to do?:
1. Display Schedules
2. Reverse Schedules
3. Insert New Item
4. Exit
1
1
Schedule for Randy
18 activities scheduled
800 : Wake up
815 : Coffee
830 : Gym
915 : Shower and breakfast
1015 : Travel to class
1030 : Class 1
1145 : Travel to Lunch
1200 : Lunch and hang with friends
1300 : Class 2
1415 : Travel to class
1430 : Class 3
1545 : Travel home
1600 : Homework and studying
1800 : Dinner with friends
1900 : Hang with friends
2000 : Homework and studying
2200 : Games, friends, and parties
2400 : Sleep
Schedule for Jamal
18 activities scheduled
800 : Wake up
815 : Coffee
830 : Gym
915 : Shower and breakfast
1015 : Travel to class
1030 : Class 1
1145 : Travel to Lunch
1200 : Lunch and hang with friends
1300 : Class 2
1415 : Travel to class
1430 : Class 3
1545 : Travel home
1600 : Homework and studying
1800 : Dinner with friends
1900 : Hang with friends
2000 : Homework and studying
2200 : Games, friends, and parties
2400 : Sleep
Schedule for Himari
18 activities scheduled
800 : Wake up
815 : Coffee
830 : Gym
915 : Shower and breakfast
1015 : Travel to class
1030 : Class 1
1145 : Travel to Lunch
1200 : Lunch and hang with friends
1300 : Class 2
1415 : Travel to class
1430 : Class 3
1545 : Travel home
1600 : Homework and studying
1800 : Dinner with friends
1900 : Hang with friends
2000 : Homework and studying
2200 : Games, friends, and parties
2400 : Sleep
What would you like to do?:
1. Display Schedules
2. Reverse Schedules
3. Insert New Item
4. Exit
Because we are using a significant amount of dynamic memory for this project, you are required to manage any memory leaks that might be created. For a linked list, this is most commonly related to the dynamically allocated nodes. Remember, in general, for each item that is dynamically created, it should be deleted using a destructor.
One way to test to make sure that you have successfully removed any of the memory leaks is to use the valgrind command.
Since this project makes extensive use of dynamic memory, it is important that you test your program for memory leaks using valgrind:
valgrind ./proj3 proj3_schedule1.txt
Note: If you accidently use valgrind make run, you may end up with some memory that is still reachable. Do not test this - test using the command above where you include the input file. The makefile should include make val (which is ok).
If you have no memory leaks, you should see output like the following:
==5606==
==5606== HEAP SUMMARY:
==5606== in use at exit: 0 bytes in 0 blocks
==5606== total heap usage: 87 allocs, 87 frees, 10,684 bytes allocated
==5606==
==5606== All heap blocks were freed -- no leaks are possible
==5606==
==5606== For counts of detected and suppressed errors, rerun with: -v
==5606== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
The important part is "in use at exit: 0 bytes 0 blocks," which tells me all the dynamic memory was deleted before the program exited. If you see anything other than "0 bytes 0 blocks" there is probably an error in one of your destructors. We will evaluate this as part of the grading for this project.
Additional information on valgrind can be found here: http://valgrind.org/docs/manual/quick-start.html
Once you have compiled using your makefile, enter the command ./proj3 to run your program. You can use make val to test each of the input files using valgrind (do NOT use valgrind make run!). They have differing sizes. It should look like the sample output provided above.
proj3.cpp
#include "Manager.h"
#include < iostream >
using namespace std;
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "You are missing a data file." << endl;
cout << "Expected usage ./proj3 proj3_schedule1.txt" << endl;
cout << "File 1 should be a file with a schedule" << endl;
}
else
{
cout << endl << "***Manager***" << endl << endl;
Manager S = Manager(argv[1]);
}
return 0;
}
Item.h
#ifndef ITEM_H
#define ITEM_H
#include < iostream >
#include < string >
using namespace std;
class Item
{
public:
// Name: Item (default constructor)
// Desc: Sets default values of a new Item (an item is a node in a linked list)
// Preconditions: None
// Postconditions: Creates a new node with a generic time and name with a pointer to nullptr
// Note: May not be used in project 3 but still implement
Item();
// Name: Item (overloaded constructor)
// Desc: Sets values of a new Item (an item is a node in a linked list)
// Preconditions: None
// Postconditions: Creates a new node using the passed name and time with a pointer to nullptr
Item(string, int);
// Name: GetName
// Desc: Returns the name of the item
// Preconditions: Item must exist
// Postconditions: Returns the name of the item
// Note: May not be used in project 3 but still implement
string GetName();
// Name: GetTime
// Desc: Returns the time of the item
// Preconditions: Item must exist
// Postconditions: Returns the time of the item
// Note: May not be used in project 3 but still implement
int GetTime();
// Name: GetNext
// Desc: Returns the pointer to the next item
// Preconditions: Item must exist
// Postconditions: Returns the pointer to the next item
// Note: May not be used in project 3 but still implement
Item* GetNext();
// Name: SetName
// Desc: Sets the name of the item
// Preconditions: Item must exist
// Postconditions: Sets the name of the item
// Note: May not be used in project 3 but still implement
void SetName(string);
// Name: SetTime
// Desc: Sets the time of the item
// Preconditions: Item must exist
// Postconditions: Sets the time of the item
// Note: May not be used in project 3 but still implement
void SetTime(int);
// Name: SetNext
// Desc: Sets the next item
// Preconditions: Item must exist
// Postconditions: Sets the next item
// Note: May not be used in project 3 but still implement
void SetNext(Item*);
// Name: operator<<
// Desc: Overloaded << operator to return ostream from an Item
// Preconditions: Requires an Item
// Postconditions: Returns ostream populated with Item's time and Item's name
// **PROVIDED** Do not edit
friend ostream &operator<< (ostream &output, Item &myItem){
output << myItem.m_time << " : " << myItem.m_name;
return output;
}
private:
string m_name; //Name of the activity
int m_time; //Time activity starts
Item* m_next; //Pointer to next node in linked list
};
#endif
Schedule.h
#ifndef SCHEDULE_H
#define SCHEDULE_H
#include < string >
#include < iostream >
#include < iomanip >
#include < cmath >
#include "Item.h"
using namespace std;
class Schedule
{
public:
// Name: Schedule() - Default Constructor
// Desc: Used to build a new Schedule
// Preconditions: None
// Postconditions: Creates a new Schedule where m_head and m_tail point to nullptr and size = 0
Schedule();
// Name: Schedule(string) - Overloaded Constructor
// Desc: Used to build a new Schedule with the schedule name passed
// Preconditions: None
// Postconditions: Creates a new Schedule where m_head and m_tail point to nullptr and schedule name is passed
Schedule(string);
// Name: ~Schedule() - Destructor
// Desc: Used to destruct a strand of Schedule
// Preconditions: There is an existing Schedule strand with at least one node
// Postconditions: Schedule is deallocated (including all dynamically allocated nodes)
// to have no memory leaks!
~Schedule();
// Name: InsertSorted
// Desc: Inserts a new item into the schedule. Inserts it from earliest time (0) to highest time (2359) ascending
// Does NOT insert at correct location when reversed
// Preconditions: Takes in an Item pointer. Inserts the node based on time.
// Requires a Schedule
// Postconditions: Adds the new item into the Schedule.
void InsertSorted(Item*);
// Name: GetName()
// Preconditions: Requires a Schedule
// Postconditions: Returns m_name;
string GetName();
// Name: GetSize()
// Preconditions: Requires a Schedule
// Postconditions: Returns m_size;
int GetSize();
// Name: ReverseSchedule
// Preconditions: Reverses the Schedule
// Postconditions: Schedule is reversed in place; nothing returned
void ReverseSchedule();
// Name: GetData
// Desc: Returns the time at a specific location in the Schedule
// Pass
// Preconditions: Requires a Schedule
// Postconditions: Returns data from specific item
// Note: May not be used in project but still required
Item* GetData(int nodeNum);
// Name: operator<<
// Desc: Allows you to cout a Schedule object
// Overloaded << operator to return ostream from Schedule
// Should not have any cout statements!
// Preconditions: Requires a Schedule sequence
// Postconditions: Returns ostream populated for each Item in Schedule
friend ostream &operator<< (ostream &output, Schedule &mySchedule);
private:
string m_name; //Name of the Schedule
Item *m_head; //Front of the Schedule
Item *m_tail; //End of the Schedule
int m_size; //Total size of the Schedule
};
#endif
Manager.h
#ifndef MANAGER_H
#define MANAGER_H
#include "Item.h"
#include "Schedule.h"
#include < fstream >
#include < string >
#include < iostream >
#include < cstdlib >
#include < vector >
using namespace std;
class Manager
{
public:
// Name: Manager (constructor)
// Desc: Creates a Manager to manage schedules
// Preconditions: None
// Postconditions: A manager is created to populate m_schedules
Manager(string fileName);
// Name: Manager (destructor)
// Desc: Deallocates all dynamic aspects of a Manager
// Preconditions: There is an existing Schedule
// Postconditions: All schedules are cleared
~Manager();
// Name: DisplaySchedules
// Desc: Displays each schedule in m_schedules
// Preconditions: At least one schedule is in m_schedules
// Postconditions: Displays all items in a schedule for all schedules in m_schedules
void DisplaySchedules();
// Name: ReadFile
// Desc: Reads in a file that has the schedule name then semicolon the starting time then a semicolon
// then the name of the activity.
// Input files are an indeterminate length. There are an indeterminate number of schedules in
// an input file. There are an indeterminate number of items in each file.
// The vector can hold many schedules.
// Preconditions: Valid file name of schedules
// Postconditions: Populates each schedule and puts in m_schedules
void ReadFile();
// Name: InsertNewItem
// Desc: Asks the user which schedule they would like to insert into (uses FindSchedule)
// If new schedule, inserts a new schedule and indicates a new schedule was created
// Prompts user for time and name of item then inserts item into schedule
// Preconditions: Populated m_schedules
// Postconditions: Either inserts into existing schedule or inserts into a new schedule
void InsertNewItem();
// Name: FindSchedule
// Desc: Returns the index of the schedule from m_schedules else -1
// Preconditions: Populated m_schedules
// Postconditions: Returns the index of schedule with the matching name or it returns -1
int FindSchedule(string schedName);
// Name: MainMenu
// Desc: Displays the main menu and manages exiting
// Preconditions: Populated m_schedules
// Postconditions: None
void MainMenu();
// Name: ReverseSchedule
// Desc: User chooses a schedule and the schedule is reversed
// If only one schedule in m_schedules, automatically reverses it without prompting the user
// Preconditions: Populated m_schedules
// Postconditions: Reverses a specific schedule replacing in place
void ReverseSchedule();
private:
vector< Schedule* > m_schedules; //Vector of all schedules
string m_fileName; //File to read in
};
#endif