I'm working on an assignment where we are to implement an address book that holds standard information (ie. Name, Address, City, State, Zip) and contains a user interface to provide options to add, delete, or modify records, search for a specific record, or display all records. These operations are to work using a linked list that holds all of the records. The program is also to be linked to an 'address.dat' file that will open in the beginning of the program and load it's information and then save any changes or additions as the program proceeds. It is this last part I am having issues with. I have the basic functions for the program working properly and have tested them. However, I am having issues figuring out how to set up the file I/O portion. I am unsure how to load the objects in a file into the linked list I have initialized in the main code. I'm pretty sure if I can figure that part out I can figure out how to add it into the other functions.

My main code is as follows:

#include <fstream>
#include <iostream>
#include <list>
#include <math.h>
#include <string.h>
#include <stdio.h>

#include "AddressRecord.h"

using namespace std;

//Prototype declarations
void menu();
void add_record();
void delete_record();
void display_record_inventory();

//Declare linked list and STL linked list variable
list <AddressRecord> address_list;

//Declare Record ID variable
int tmpid=0;

//Declare data file variable
fstream data_file; 


//Main program. Calls functions to load the address book into memory then launches the user menu.
int main (int argc, char **argv)
{
	data_file.open("address.dat", ios::in|ios::app);

	menu();

	return 0;
}

//Function to add a record to the linked list.
void add_record()
{
	AddressRecord address_record;
	string tmpstr;
		
	cout << endl << "**ADD ADDRESS TO RECORD BOOK**" << endl << endl;

	tmpid++;
	address_record.setRecordId(tmpid);

	getline (cin, tmpstr); //Ignore the first CR

	cout << "First Name: ";
	getline (cin, tmpstr, '\n');
	address_record.setFirstName(tmpstr);

	cout << "Last Name: ";
	getline(cin, tmpstr, '\n');
	address_record.setLastName(tmpstr);

	cout << "Contact Type: ";
	getline (cin, tmpstr, '\n');
	address_record.setContactType(tmpstr);

	cout << "Street Address: ";
	getline (cin, tmpstr, '\n');
	address_record.setStreetAddress(tmpstr);

	cout << "City: ";
	getline (cin, tmpstr, '\n');
	address_record.setCity(tmpstr);

	cout << "State: ";
	getline (cin, tmpstr, '\n');
	address_record.setState(tmpstr);

	cout << "Zip Code: ";
	getline (cin, tmpstr, '\n');
	address_record.setZipCode(tmpstr);

	//Add to the linked list
	address_list.push_back(address_record);

	return;
}

//Function to delete a record based on RecordID
void delete_record()
{
	cout << endl << "**DELETE AN ADDRESS FROM THE RECORD BOOK**" <<endl <<endl;

	string tmp_lastname_str;
	bool found_entry = false;
	AddressRecord address_record;

	cout << "Last Name: ";
	cin >> tmp_lastname_str;

	list<AddressRecord>::iterator i;
	for (i = address_list.begin(); i != address_list.end();)
	{
		address_record = *i;

		if (address_record.getLastName() == tmp_lastname_str)
		{
			found_entry = true;
			i = address_list.erase(i);
		}
		else
		{
			++i;
		}
	}

	if (found_entry)
		cout << "Entry deleted." << endl;
	else
		cout << "Entry not found." << endl;

	return;
}
void find_record()
{
	cout << endl << "**FIND AN ADDRESS IN THE RECORD BOOK**" <<endl <<endl;

	string tmp_lastname_str;
	bool found_entry = false;
	AddressRecord address_record;

	cout << "Last Name: ";
	cin >> tmp_lastname_str;

	list<AddressRecord>::iterator i;
	for (i = address_list.begin(); i != address_list.end();)
	{
		address_record = *i;

		if (address_record.getLastName() == tmp_lastname_str)
		{
			found_entry = true;
			cout << "Record ID: " << address_record.getRecordId() << endl;
			cout << "First Name: " << address_record.getFirstName() << endl;
			cout << "Last Name: " << address_record.getLastName() << endl;
			cout << "Contact Type: " << address_record.getContactType() << endl;
			cout << "Street Address: " << address_record.getStreetAddress() << endl;
			cout << "City: " << address_record.getCity() << endl;
			cout << "State: " << address_record.getState() << endl;
			cout << "Zip Code: " << address_record.getZipCode() << endl;
			cout << "-----------------------------------------------------" << endl;
			return;
		}
		else
		{
			++i;
		}
	}

	if (found_entry);
	else
		cout << "Entry not found." << endl;

	return;
}
void modify_record()
{
	cout << endl << "**MODIFY AN ADDRESS IN THE RECORD BOOK**" <<endl <<endl;

	int tmp_id;
	string tmpstr;
	bool found_entry = false;
	AddressRecord address_record;

	cout << "Record ID: ";
	cin >> tmp_id;

	list<AddressRecord>::iterator i;
	for (i = address_list.begin(); i != address_list.end();)
	{
		address_record = *i;

		if (address_record.getRecordId() == tmp_id)
		{
			found_entry = true;
			getline (cin, tmpstr); //Ignore the first CR

			cout << "First Name: ";
			getline (cin, tmpstr, '\n');
			i->setFirstName(tmpstr);

			cout << "Last Name: ";
			getline(cin, tmpstr, '\n');
			i->setLastName(tmpstr);

			cout << "Contact Type: ";
			getline (cin, tmpstr, '\n');
			i->setContactType(tmpstr);

			cout << "Street Address: ";
			getline (cin, tmpstr, '\n');
			i->setStreetAddress(tmpstr);

			cout << "City: ";
			getline (cin, tmpstr, '\n');
			i->setCity(tmpstr);

			cout << "State: ";
			getline (cin, tmpstr, '\n');
			i->setState(tmpstr);

			cout << "Zip Code: ";
			getline (cin, tmpstr, '\n');
			i->setZipCode(tmpstr);

			cout << "Entry modified." << endl;
			return;
		}
		else
		{
			++i;
		}
	}

	if (found_entry);
	else
		cout << "Entry not found." << endl;

	return;
}
void display_record_inventory()
{
	cout <<endl << "**DISPLAY RECORD BOOK**" << endl << endl;

	string continue_display;
	AddressRecord address_record;

	list<AddressRecord>::iterator i;
	int j = 0;
	for (i = address_list.begin(); i != address_list.end(); ++i, j++)
	{
		address_record = *i;

		cout << "Record ID: " << address_record.getRecordId() << endl;
		cout << "First Name: " << address_record.getFirstName() << endl;
		cout << "Last Name: " << address_record.getLastName() << endl;
		cout << "Contact Type: " << address_record.getContactType() << endl;
		cout << "Street Address: " << address_record.getStreetAddress() << endl;
		cout << "City: " << address_record.getCity() << endl;
		cout << "State: " << address_record.getState() << endl;
		cout << "Zip Code: " << address_record.getZipCode() << endl;
		cout << "-----------------------------------------------------" << endl;

		//Print first ten records, then ask user if he/she wants to continue displaying
		if (j != 0 && j%10 == 0)
		{
			cout<< "Continue Display? (y/n) ";
			cin >> continue_display;
			if (strncmp(continue_display.c_str(), "y", 2))
			{
				return;
			}

			cout << "-----------------------------------------------------" << endl;
		}
	}
	
	return;
}

//Main user menu
void menu()
{
	char option[3];
	bool exit_program = false;

	while (!exit_program)
	{
		//Allow user to select options to add, delete, modify, and list all data
		//in the address book.
		cout << endl << "**Address Book Main Menu**" << endl << endl;
		cout << "     1. Add entry" << endl;
		cout << "     2. Delete entry" << endl;
		cout << "     3. Find entry" << endl;
		cout << "     4. Modify entry" << endl;
		cout << "     5. Display all entries" << endl;
		cout << endl << "     99. Exit program" << endl  << endl;

		cout <<  "Option: ";
		cin >> option;

		//Process user entry
		switch (atoi(option))
		{
		case 1:
			add_record();
			break;
		
		case 2:
			delete_record();
			break;

		case 3:
			find_record();
			break;

		case 4:
			modify_record();
			break;

		case 5: 
			display_record_inventory();
			break;

		//Save address book and exit program
		case 99:
			exit_program = true;
			break;

		default:
			cerr << "Error: unknown option!" << endl;
			break;
		}
	}

	return;
}

Address.h is just a simple class definition, but I'm including it as a view of the whole program.

#ifndef _ADDRESS_RECORD_H_
#define _ADDRESS_RECORD_H_

#include <iostream>
#include <string>

using namespace std;

class AddressRecord
{
public:
	AddressRecord();
	AddressRecord(const AddressRecord &addressRecord);
	~AddressRecord();

	void setRecordId(int recordId);
	int getRecordId() const;

	void setFirstName(string firstName);
	string getFirstName() const;

	void setLastName(string lastName);
	string getLastName() const;

	void setContactType(string contactType);
	string getContactType() const;

	void setStreetAddress(string streetAddress);
	string getStreetAddress() const;

	void setCity(string city);
	string getCity() const;

	void setState(string state);
	string getState() const;

	void setZipCode(string zipCode);
	string getZipCode() const;

private:
	int recordId;
	string firstName;
	string lastName;
	string contactType;
	string streetAddress;
	string city;
	string state;
	string zipCode;
};

#endif

Any suggestions or explanations would be much appreciated.

Well first, you are going to want to modify your add_record function. It is better practice to do most of your cout's and cin's in main (or in this case you can also do them in menu() ) and pass the arguments to the function to add them to the list. If you do it this way, you can also use the add_record function in a while loop to import the records from your file.

Edited 6 Years Ago by hag++: n/a

Thanks for the suggestion. I got some additional prompts from my professor and figured out a way to do it with new functions that mirrored my add and display

int address_load()
{
	AddressRecord address_record;
	string tmpstr;

	while (!data_file.eof())
	{
		getline(data_file, tmpstr);
		while (!tmpstr.empty())
		{
			int StrConvert; 
			StrConvert = atoi(tmpstr.c_str());
			address_record.setRecordId(StrConvert);

			getline(data_file, tmpstr);
			address_record.setFirstName(tmpstr);

			getline(data_file, tmpstr);
			address_record.setLastName(tmpstr);

			getline(data_file, tmpstr);
			address_record.setContactType(tmpstr);

			getline(data_file, tmpstr);
			address_record.setStreetAddress(tmpstr);

			getline(data_file, tmpstr);
			address_record.setCity(tmpstr);

			getline(data_file, tmpstr);
			address_record.setState(tmpstr);

			getline(data_file, tmpstr);
			address_record.setZipCode(tmpstr);

			address_list.push_back(address_record);

			tmpstr.clear();
		}
			}
	return 0;
}
//Function to save all data from list to address.dat
int address_save()
{
	if(!address_open(ios_base::out))
	{
		cout << "Creating data file." << endl;
	}

	AddressRecord address_record;
	
	list<AddressRecord>::iterator i;
	
	for (i = address_list.begin(); i != address_list.end(); ++i)
	{
		address_record = *i;

		data_file << address_record.getRecordId() << endl;
		data_file << address_record.getFirstName() << endl;
		data_file << address_record.getLastName() << endl;
		data_file << address_record.getContactType() << endl;
		data_file << address_record.getStreetAddress() << endl;
		data_file << address_record.getCity() << endl;
		data_file << address_record.getState() << endl;
		data_file << address_record.getZipCode() << endl;
		
	}
	
	cout << "Data file saved." << endl;
	address_close();

	return 0;
}

Then all I had to do was update my tmp_id variable to the value of the RecordId in the last node of the list.

This article has been dead for over six months. Start a new discussion instead.