1. Overview

In this project you will:

  • Implement a linked-list data structure,
  • Use dynamic memory allocation to create new objects,
  • Practice using C++ class syntax,
  • Practice object-oriented thinking.

2. Background

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.

3. Assignment Description

Your assignment is to build an application that will allow the user to create multiple schedules.

4. Requirements:

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).

  • The project must be completed in C++. You may not use any libraries or data structures that we have not learned in class. No breaks CMSC 202 - Computer Science II Page 2 (except in switch statements), continues, or exit(). Libraries we have learned include < iostream >, < fstream >, < iomanip >, < vector >, < cstdlib >, < time.h >, < cmath >, and < string >. You should only use namespace std.
  • You must use the function prototypes as outlined in the Item.h, Schedule.h and Manager.h header file. Do not edit the header files.
  • There are several input files to test including proj3_schedule1.txt, proj3_schedule2.txt, proj3_schedule3.txt. There is no defined maximum number of schedules and no defined number of items in each schedule. Each input file can have one or more schedules in it. Figure 1 shows details about the input files. Please note that in schedule 1, the name of the schedule is "1". There could be many items in each input file. The delimiter for project 2 will be a semicolon.
  • The node class is called Item and contains three pieces of data: A start time of the activity (m_time), a name for the activity (m_name), and a pointer to the next item (m_next). All variables in the Item class are private and must be accessed using getters.
    • Item (default constructor) - creates a "New Item" with a time of 0 and m_next = nullptr;
    • Item (Overloaded constructor) - uses data passed to populate member variables
    • Setters and Getters (may not be used explicitly but need to be implemented)
    • Overloaded << operator - Allows user to print a specific node. Provided in .h file.
  • The linked list class is called Schedule and contains four pieces of data: A name for the schedule (m_name), an Item pointer tracking the front of the Schedule (m_head), an Item pointer tracking the end of the Schedule (m_tail), and an integer tracking the size of Schedule (m_size).
    • Schedule (Default) - creates a new schedule with name of "Default" and pointers = nullptr and m_size = 0;
    • Schedule(Overloaded) - populates the name based on passed value and pointers = nullptr and m_size = 0;
    • ~Schedule - Destructs the whole schedule
    • InsertSorted - Inserts a new Item into the schedule from earliest time (0) to greatest time (2359) inclusive. Time is represented using 0 as midnight and 2359 as 11:59pm.
    • Getters - May not be used explicitly in project but you must implement them.
    • ReverseSchedule - Reverses the schedule based on time. Can be called multiple times. Reverses schedule in place and cannot create a new schedule.
    • GetData - Returns an Item pointer at a specific location. Passed the number of the node you would like to return from 0 to size-1. May not be used explicitly in project but you must implement it.
    • Overloaded << operator - Allows user to print a schedule object. Iterates over entire schedule and populates the output stream. Look at the example in Item.h for more hints.
  • The class managing the loading of files, the user input, and the schedules is called Manager. It has two pieces of data: a vector to hold the Schedules (m_schedules) and a string holding the name of the input file (m_fileName).
    • Manager(Overloaded) - Creates a new manager object that is passed the file name to load.
    • ~Manager - Destructor for the manager
    • DisplaySchedules - Displays all schedules available in m_schedules
    • ReadFile - Reads in a line from the input file and adds an Item in the corresponding schedule. Each input file can have many different schedules and items.
    • FindSchedule - Used to identify which schedule to insert an item in ReadFile.
    • MainMenu - Lists each of the options: 1. Display Schedules, 2. Reverse Schedule, 3. Insert New Item, and 4. Exit. Calls the corresponding function as needed.
    • DisplaySchedules - Displays each schedule in m_schedules
    • ReverseSchedule - Allows user to choose one schedule to reverse. If there is only one schedule, automatically reverses that schedule.
    • InsertNewItem - Allows user to insert an item into a schedule of their choice including a new one. Requests the name of the schedule to insert into, the start time of the activity, and the name of the activity. There are no checks on duplicative times e.g., you could have two things start at 8am. If you insert a new item into a reversed schedule, it will insert the new item incorrectly you do not need to correct for this!
  • All user inputs will be assumed to be the correct data type. For example, if you ask the user for an integer, they will provide an integer.
  • Regardless of the sample output below, all user input must be validated. If you ask for a number between 1 and 5 with the user entering an 8, the user should be re-prompted.

5. Sample Input and Output

5.1. Sample Run

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

6. Compiling and Running

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.

Starter Codes

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
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.