This project will help you show your mastery of arrays, C-strings, classes, and libraries.
Write a program to handle a user's rolodex entries. (A rolodex is a system with tagged cards each representing a contact. It would contain a name, address, and phone number. In this day and age, it would probably have an email address as well.)
Typical operations people want to do to a rolodex entry are:
1) Add entry 2) Edit entry 3) Delete entry 4) Find entry 5) Print all entries 6) Quit
You can decide what the maximum number of rolodex entries is and how long each part of an entry is (name, address, etc.).
When they choose to edit an entry, give them the option of selecting from the current rolodex entries or returning to the main menu — don't force them to edit someone just because they chose that option.
Similarly for deleting an entry. Also don't forget that when deleting an entry, you must move all following entries down to fill in the gap.
If they want to add an entry and the rolodex is full, offer them the choice to return to the main menu or select a person to overwrite.
When they choose the print option, make a nicely formatted table of their current entries (if any). (See the class roster lab for an example of a fine table format — and possible gotcha's.)
When they choose to find an entry, go to a submenu:
1) find by Name 2) find by Address 3) find by Phone number 4) find by Email address 5) Return to Main Menu
All of these searches are to be case-insensitive content searches. (In other words, if the rolodex contains a person named Vishal Herrera, they should be found by searches by name of: sh, SH, al h, al H, herrera, HERRERA, etc. as well as of Vishal Herrera.)
Question: Should you print all matches to a search or just the first one?
All menus are to be choosable by both number and capitalized letter(s).
Hint: You'll only have one class — most likely. It might look something like this:
const size_t MAX_NAME = ???, MAX_STREET = ???, MAX_TOWN = ???, MAX_STATE = 3, MAX_PHONE = 14, // ...other MAX's... class RolodexEntry { char fname[MAX_NAME], lname[MAX_NAME]; // together or separate? char street[MAX_STREET], town[MAX_TOWN], state[MAX_STATE]; long zip; short zip_4; char phone[MAX_PHONE]; public: // ...ctor's, accessors, mutators, i/o, equality, etc. };
(But see the options below...)
Hint: This class should have its own library. Other libraries may also be used for collections of functions (like a generic list searching function? or special string searching functions).
This assignment is (Level 4).
Add (Level 3) to add a sorting option to the main menu. If they choose to sort, you must let them pick which data item to sort on (name, address, etc.). Then sort the rolodex entries as they requested.
Tip: Have your class provide a compare method which returns similarly to strcmp (negative, 0, or positive). Its arguments should be a string to compare with and some indication as to which of the data fields to compare the string to (maybe a char or short with provided constants the caller could pass; maybe even an enumeration!). Something like:
enum CompTo { Name, Street, Town, ... }; class RolodexEntry { public: short compare(const char comp_this[], CompTo to_this); };
Tip: If you remember that the list is sorted on item X, you can use a binary search when they search for an entry by X next time.
Add (Level 2.5) to add load and save options to the main menu. These will load from a file or save to a file (user specified, of course). Of course, you will determine the data format of the rolodex files.
When they choose the save option, you will save the current list entries in a file. (Make sure they can specify the file to save their entries in.)
When they choose the load option, you will retrieve entries (previously saved) from a file into the current list. (Let them choose which file to load entries from.) Also it would be good to allow them to decide whether to overwrite the current entries (if any) before you load new entries in. (Perhaps allow them to merge if there is room left in the current rolodex list..?)
Oh, what the heck: add another (Level 4) to make your list of entries dynamic so that it resizes when they have more than you currently have room for. (This is technically its own separate option, but this is the only context in which I see students coming across the absolute desire/need for it.)
Add (Level 4) to use a labeled block data format for your rolodex files. Although you may only need to translate string's for your data's types, you must provide translation functions for all basic types (short, long, double, float, char, char[], bool) to get full option credit here.
Hint: What items make up a data block? What default values would be reasonable for missing items in a data block?
Add (Level 3) more if your 'labeled' format is XML (or at least XML-like). XML uses a system of tags similar to HTML. The example file from the related lab might look like this as XML:
<student> <name>Jason James</name> <id>123456</id> <gpa>9.2</gpa> <grade>B</grade> </student> <student> <name>Tammy James</name> <gpa>11.2</gpa> <grade>A</grade> <id>123457</id> </student> <student> <name>Henry Ramirez</name> <gpa>12.3</gpa> <id>111888</id> <major>ChE</major> <class>soph</class> </student> <student> <id>788531</id> <name>Suzie Shah</name> <grade>Q</grade> </student>
Note how some problems mentioned in that lab are removed by the rigid structure but others are created. Here's a brief introduction to the syntax of XML.
Add (Level 2) to mark entries as deleted instead of shifting all remaining entries down in the list. This will affect edit, print, save, sort (if you did that option), and even add. (How, after all, will add know the list is full if there are entries missing in the middle that can be used?) Will this affect your ability to binary search instead of linear search for sorted fields?
You can even add another (Level 2) to implement an undelete feature that shows them the previously deleted entries and allows them to put them back into place in the list.
Add (Level 2) to detect whether the user entered a number or a name at prompts involving a list of the people (including overwrite, delete, and edit). If they've entered a number, proceed as normal. If they've entered a name, use your search capability to decide which contact it was. (If the name matches multiple contacts, you should print a new — hopefully smaller — list of the matches for them to choose from.)
Add (Level 3) to add a second class to manage the list of rolodex entries. This will keep the main uncluttered by list management details. (This can be difficult, though. Keep straight in your head what is a rolodex entry behavior and what is a rolodex/list behavior!)
To get you started:
const size_t MAX_ENTRIES = ???; class Rolodex { RolodexEntry list[MAX_ENTRIES]; size_t current; public: bool full(void) const { return current == MAX_ENTRIES; } RolodexEntry get(size_t index) const; bool set(size_t index, const RolodexEntry & new_entry); bool add(const RolodexEntry & new_entry); // other methods and constructors };