Linked Lists I
This assignment demonstrates linked lists and how they can be managed from an object oriented design perspective.
Create a ShellCatalog application that maintains a list of Shells and some information about them. The information must be encapsulated in a class called Shell. The following code should be the contents of your Shell.h file:
const int ENTRY_SZ = 256;
class Shell
{
private:
char name_[ENTRY_SZ];
char color_[ENTRY_SZ];
double mass_;
double length_;
public:
// Store the path name of the Shell catalog file
static char filePath_[ENTRY_SZ];
Shell();
Shell(char* name);
void SetColor(char* color);
void SetMass(double mass);
void SetLength(double rad);
void SetMass(char* mass);
void SetLength(char* rad);
void PrintToConsole();
void AppendToFile();
};
Note that then numeric Set methods are overloaded so that they may be called with numeric or character parameters. Your program does not have to call both of these but it is good to include them both so that they are available to be used. Can you think of a reason why each could be used?
The application must use an unordered linked list to hold all the Shells in memory. We will create a linked list without using templates to illustrate an alternative method from what is presented in the text book. Our linked list will be generic in that it will not refer to the Shell class at all. That way, your linked list class can be used to store any type of data, without the use of templates. In this case the linked list will be able to store a list of any kind of objects, including Shell objects. The linked list will even be able to store a mixture of different types of objects.
Your program must use the Node struct and LinkedList class shown below, defined in LinkedList.h. The Node class has a data_ property that points to a Shell object, but notice that it is of type void*. A void pointer is used so that this class does not have to know about the Shell class. The LinkedList class has a first_ property that points to the first Node in the list and a last_ property that points to the last Node in the list.
struct Node
{
void* data_;
Node* next_;
Node()
{
data_ = 0;
next_ = 0;
}
};
class LinkedList
{
private:
Node* first_;
Node* last_;
long listLen_;
public:
LinkedList();
~LinkedList();
void AddLinkToBack(void* ptr);
void* RemoveLinkFromFront();
Node* GetFirstNode();
long GetListLength();
};
A memory picture of these three constructs (Shell class, LinkedList class, and the Node struct) is shown below. The Node objects are contained in the linked list. The LinkedList class can directly access the first and last entries in the list. The data_ property of the Node class is of type void*, which means it can contain the address of any type of object. You are going to store the address of Shell objects in them. As you can see, there is one Node object associated with each Shell object. So for each Shell that your program reads in from a file or gets from the console, it must create a new Shell object and a new Node object.
When the application runs it must display a console menu that looks like this:
a)Open a Shell catalog file
b)Add a new Shell
c)Print all Shell data
d)Clear list
e)Quit
When a) is selected, the program must prompt the user to enter a file path for an input Shell catalog file. It should open the file and read the data for each Shell from the file one at a time. Note that each Shell is on a line where each value is comma separated, such as:
Beaded Periwinkle, white, 0.15, 8.8
Fighting conch, yellow, 0.14, 4.6
For each Shell, it should dynamically create a Shell object (using new), store the Shell data into the object, and add that object to the linked list (which means it must dynamically create a Node object as well). A Shell catalog file is provided and is called ShellCatalog.txt. The Shell object must be created and deleted in the main function, and the Node objects should be created and deleted in the LinkedList class. It is generally better to prevent the main function from needing to know anything about the Node type. That is a storage detail and should be hidden.
When a) is selected a second time, the program must delete every link in the list before reading the new Shell catalog file. This should be done in a function in the main file calling RemoveLinkFromFront in a loop until it returns null, indicating that there are no more nodes left. The returned void pointer value from the function must be cast to a Shell object before being deleted. Remember that the Shell and the Node objects must be deleted using the delete keyword.
The b) option should prompt the user to enter the data for a new Shell. The program must dynamically create a Shell object (using new), store the data into the object, and add that object to the linked list (which means it must dynamically create a Node object as well). After that link is added, the program must append the contents of the linked list to the same Shell file.If a shell file has not been opened yet, display an error message stating that.
The c) option should print the Shell data to the console with appropriate formatting.
The d) option should empty the linked list by calling a recursive function. Note that because it must delete each Shell object associated with each list node, this function must not be in the LinkedList class.
Some Details:
- If your program opens and closes a file more than one time, which it probably does, add the following clear statement each time after closing it (otherwise, some compilers, like mine, will not allow the file to be reopened):
inFile.close();
inFile.clear(std::ios_base::goodbit); - The LinkedList class must not contain any reference to the Shell class. The LinkedList.h and LinkedList.cpp files should also not contain #include “Shell.h”.
- When adding links to the list, use the AddLinkToBack() method.
- When deleting links, use the RemoveLinkFromFront() method.
- The main function should look very similar to this:
void main()
{
bool terminate = false;
char selection;
while (!terminate)
{
selection = DisplayMenu();
switch(selection)
{
case 'a':
LoadTextFile();
break;
case 'b':
AddNewShell();
break;
case 'c':
PrintAllShellData();
break;
case 'd':
ClearList();
break;
case 'e':
terminate = true;
break;
default:
cout < "That is not a valid choice!\n";
}
}
}
Usage Examples:
User entries are bolded:
Please make a selection:
a) Open a shell catalog file
b) Add a new shell
c) Print all shell data
d) Clear list
e) Quit
a
Enter the full file path: C:\Users\Gery\Dropbox\Teaching\PCC\CS162\Homeworks\Set2\Hmwk3\shellCatalog.txt
Loaded file and read 5 shell objects.
Please make a selection:
a) Open a shell catalog file
b) Add a new shell
c) Print all shell data
d) Clear list
e) Quit
c
Beaded Periwinkle, white, 0.15, 8.8
Paper Fig, amber, 0.45, 33.4
Lace Murex, brown, 0.33, 22.3
Fighting conch, yellow, 0.14, 4.6
Sunray Venus, blue, 0.09, 3.4
Please make a selection:
a) Open a shell catalog file
b) Add a new shell
c) Print all shell data
d) Clear list
e) Quit
b
Enter the shell name: Florida Cerith
Enter the shell color: Beige
Enter the shell mass: 45
Enter the shell length: 11.33
Please make a selection:
a) Open a shell catalog file
b) Add a new shell
c) Print all shell data
d) Clear list
e) Quit
c
Beaded Periwinkle, white, 0.15, 8.8
Paper Fig, amber, 0.45, 33.4
Lace Murex, brown, 0.33, 22.3
Fighting conch, yellow, 0.14, 4.6
Sunray Venus, blue, 0.09, 3.4
Florida Cerith, Beige, 45, 11.33
File Organization:
Put the Shell class declaration in a header file called Shell.h. Put the Shell class method definitions in a source file called Shell.cpp. Put the Node and LinkedList class definitions in corresponding files LinkedList.h and LinkedList.cpp and the main program into a main file called main.cpp.
Deliverables:
Upload the Shell.cpp, Shell.h, LinkedList.cpp, LinkedList.h and main.cpp files only. Any other files, including zip files, will not be accepted.