Missionary Referral Manager

Problem

  • Your mission president found out that you are a programmer and needs you to build a program to track and manage referrals (names only for now)
  • Specifically the program needs to be able to
    • Display all referrals
    • Add a referral
    • Display all referrals sorted by name
    • Load a list of referrals (one name per line)
    • Save a list of referrals (one name per line)
  • You only need to worry about tracking names for now
  • Referrals have in the past been stored in files in CSV (Comma Separated Values) files formatted this way:
    • Name Phone# Area
  • For example:
    • Paul Bodily 1-541-123-4567Orem South
  • Adapt your program to be able to load referrals saved in this format

Solution

/*
Test cases should be made to test each option under various conditions (e.g., empty vs non-empty list,
multi-word input vs single-word input, files w/ and w/o phone numbers, etc)
*/
 
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
 
using namespace std;
 
const int DISPLAY_ALL_OPT = 1;
const int ADD_OPT = 2;
const int DISPLAY_SORTED_OPT = 3;
const int LOAD_OPT = 4;
const int SAVE_OPT = 5;
 
/*
	Print menu and prompt for user's choice
	@return user's menu choice
*/
int prompt_for_choice()
{
	cout << "*********MENU***********" << endl
		<< DISPLAY_ALL_OPT << ". Display all referrals" << endl
		<< ADD_OPT << ". Add a referral" << endl
		<< DISPLAY_SORTED_OPT << ". Display all referrals sorted by name" << endl
		<< LOAD_OPT << ". Load a list of referrals" << endl
		<< SAVE_OPT << ". Save a list of referrals" << endl
		<< "Choice? ";
 
	int choice;
	cin >> choice;
 
	cout << endl;
	return choice;
}
 
/*
	displays a list of strings with a 1-based ordering label
	@param list a list of strings to display
*/
void display_list(const vector<string> & list)
{
	cout << "LIST ELEMENTS" << endl;
	for (int i = 0; i < list.size(); i++)
	{
		// print 1-based index and each element
		cout << (i + 1) << ". " << list[i] << endl;
	}
}
 
/*
	Prompts for name to add and adds name to list
*/
void add_referral(vector<string> & names)
{
	cout << "Name:";
	string name;
 
	cin.sync();
	getline(cin, name);
 
	names.push_back(name);
}
 
/*
	Displays list sorted alphabetically without modifying original list
	@param list to be displayed sorted
*/
void display_sorted(const vector<string> & list)
{
	vector<string> copy_to_sort = list;
 
	sort(copy_to_sort.begin(), copy_to_sort.end());
 
	//copy_to_sort is now sorted
	display_list(copy_to_sort);
}
 
/*
	Prompts user for filename and then replaces list of names with list from the specified file
	Note that if file doesn't exist, then list stays the same
	@param names list to fill with file contents
*/
void load_from_file(vector<string> & names)
{
	cout << "File to load:";
	string filename;
 
	cin.sync(); // We need this in case there's a "\n" sitting in  cin from cin >> choice in the menu prompt
	getline(cin, filename); // We can get names with multiple words
 
	ifstream in_file;
	in_file.open(filename);
 
	if (in_file.fail()) // Checks if file can be read
	{
		cout << "Couldn't load file" << endl;
		return;
	}
 
	names.clear(); // remove all current elements from the list
 
	string next_line;
	while (getline(in_file, next_line))
	{
		// The file may contain a phone number after the name for each person
		// We need to find the position of the first number and get a substring of just the name
 
		int i = 0;
		while (!isdigit(next_line[i]))
		{
			i++;
		}
		// i is now the position of the first number in the line
 
		int j = i - 1;
		while (isspace(next_line[j]))
		{
			j--;
		}
		// j is now the position of the last non-space before the first number
 
		string name = next_line.substr(0, j+1);
 
		names.push_back(name);
	}
 
	cout << names.size() << " elements were loaded" << endl;
}
 
/*
	Saves the list to a file with filename prompted for as part of function
	@param names list to save to a file
*/
void save_to_file(vector<string> & names)
{
	cout << "Filename:";
	string filename;
 
	cin.sync(); // We need this in case there's a "\n" sitting in  cin from cin >> choice in the menu prompt
	getline(cin, filename); // We can get names with multiple words
 
	ofstream out_file;
	out_file.open(filename);
 
	if (out_file.fail())
	{
		cout << "Couldn't write to file" << endl;
		return;
	}
 
	for (int i = 0; i < names.size(); i++)
	{
		// Print just like you would to cout
		out_file << names[i] << endl;
	}
}
 
int main()
{
	vector<string> names;
 
	while (true)
	{
		int choice = prompt_for_choice();
		if (choice == DISPLAY_ALL_OPT)
		{
			cout << "DISPLAY REFERRAL LIST" << endl;
			display_list(names);
 
		}
		else if (choice == ADD_OPT)
		{
			cout << "ADD REFERRAL" << endl;
			add_referral(names);
		}
		else if (choice == DISPLAY_SORTED_OPT)
		{
			cout << "DISPLAY SORTED REFERRAL LIST" << endl;
			display_sorted(names);
		}
		else if (choice == LOAD_OPT)
		{
			cout << "LOAD REFERRAL LIST" << endl;
			load_from_file(names);
		}
		else if (choice == SAVE_OPT)
		{
			cout << "SAVE REFERRAL LIST" << endl;
			save_to_file(names);
		}
 
		cout << endl;
	}
 
 
	system("pause");
	return 0;
}
cs-142/missionary-referral-manager.txt · Last modified: 2015/05/26 12:17 by cs142ta
Back to top
CC Attribution-Share Alike 4.0 International
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0