Okay, well, I got my Address Book project done on time :) My current project is to turn it into a class. I have been working on this for a while and I keep getting set back to square one. My biggest problem is with writing some sort of user interface while dealing with private variables. I have read some posts by the Queen of Daniweb, which were helpful, but I can't get to her tutorial.... anyway, if someone could just explain how a person interfaces with private variables, I would appreciate it. Just something to get me started. Anyway, here's the code so far:

// Header file first


#ifndef _ADDRESSBOOK
#define _ADDRESSBOOK

const int MAXADDRESS = 25;

class PERSON
{
private:
	char fName[25];
	char lName[25];
	char Address[100];
	char people[MAXADDRESS];

public:
	
	bool addPerson(const PERSON &p);
	bool getPerson(PERSON &p);
	bool findPerson(char *lastName, PERSON &p);
	bool findPerson(char *lastName, char *firstName, PERSON &p);
	void printBook(PERSON &p);
};


#endif

//Now the cpp with all the functions...

#include <iostream>
using namespace std;
#include "definitionsAddressBook.h"

using namespace std;

int head = 0;
int tail = -1;


bool PERSON::addPerson(const PERSON &p)
{
	
if(head < MAXADDRESS)
{

	people[head] = p;
	head++;
	if(tail == -1)
		tail++;
	return true;
}
return false;
}
bool PERSON::getPerson(PERSON &p)
{

	if(tail >=0)
	{

		if(tail >= MAXADDRESS)
			tail = 0;
		p = people[tail];
		tail++;
		
		return true;

	}
return false;
}
bool PERSON::findPerson(char *lastName, PERSON &p)
{

	for(int i = 0; i < head; i++)
	{
		if(!_stricmp(people[i].lName, lastName))

		{
			p = people[i];
			return true;

		}

	}
return false;
}
bool PERSON::findPerson(char *lastName, char *firstName, PERSON &p)
{

	for(int i = 0; i < head; i++)
	{

		if(!_stricmp(people[i].lName, lastName) && !_stricmp(people[i].fName, firstName))

		{
			p = people[i];
			return true;

		}

	}
return false;
}
void printBook(PERSON &p)
{


	for(int i = 0; i < MAXADDRESS; i++)
	{
 
		cout << people[i].fName << "\t" << people[i].lName << "\t" << people[i].Address << endl;

	}

}



// Now the main cpp

#include <iostream>
using namespace std;

#include "definitionsAddressBook.h"
#include "conio.h"


using namespace std;
int printMenu();
void waitKey();

const int ADDPERSON = 1;
const int GETPERSON = 2;
const int FINDLAST = 3;
const int FINDBOTH = 4;
const int PRINT = 5;
const int EXIT = 0;
int main()
{

	int selection;
	PERSON p;
	PERSON access;
	bool status;
	char fName[50];
	char lName[50];
	char Address[100];
	char *firstName;
	char *lastName;
	char *address2;



	selection = printMenu();
	while(selection != EXIT )
		{
			switch(selection)
				{
			case ADDPERSON :
				
				cout << "Enter First Name " << endl;
				cin >> p.fName;
				cout << "Enter last Name " << endl;
				cin >> p.lName;
				cout << "Enter Address " << endl;
				cin >> p.Address;


				status = access.addPerson(p);
				if(status == false)
					cout << "Sorry There is no more room in the address book " << endl;

				else
					cout << "Thanks for your Entry " << endl;


				waitKey(); 
				break;

			case GETPERSON :

				status = access.getPerson(p);
				if(status)
					cout << p.fName << "\t" << p.lName << " " << p.Address << endl;
				else
					cout << "Sorry The address book is empty " << endl;

				waitKey();
				break;


			case FINDLAST :


				cout << "Enter a last name " << endl;
				cin >> lName;
				status = access.findPerson(lName, p);

				if(status)
					cout << p.fName << "\t" << p.lName << " " << p.Address << endl;
				else
					cout << "Sorry, Name not found " << endl;
				waitKey();

				break;


			case FINDBOTH :

				cout << "Enter last name " << endl;
				cin >> lName;
				cout << "Enter first name " << endl;
				cin >> fName;
				status = access.findPerson(lName, fName, p);

				if(status)
					cout << p.fName << "\t" << p.lName << " " << p.Address << endl;
				else
					cout << "Sorry, Name not found " << endl;

				waitKey();
				break;


			case PRINT :

				printBook();
				waitKey();

				break;
			case EXIT :

				cout << "Thanks for using the address book " << endl;
				exit(0);

			}
			selection = printMenu();

	}
}

int printMenu()
{

	int selection;


	system("CLS");

	cout << "1. Add A Person" << endl;
	cout << "2. Get A Person " << endl;
	cout << "3. Find A person By Last Name " << endl;
	cout << "4. Find A person By First and Last Name " << endl;
	cout << "5. Print the address book" << endl;
	cout << "0. Exit this program " << endl;
	cin >> selection;

	return selection;

}

void waitKey()
{

	cout << "Press a key to continue " << endl;

	while(!kbhit())
		;

	getch();
	fflush(stdin);

}

Anyway, I can't have any cin or cout in the functions - beileve me, I already tried. If anybody has a suggestion, I would really appreciate it.

Recommended Answers

All 11 Replies

The code as posted has a few problems:

In combination with const int MAXADDRESS = 25; , the statement char people[MAXADDRESS]; declares an array of 25 characters.

But later in methods of the class, you treat people like it was an array of PERSON.

See: people[head] = p; and p = people[tail]; for examples. (This shouldn't even compile, doesn't your compiler complain about it?)

You also have methods which you appear to intend to 'return' a value through a PERSON reference. For example: bool PERSON::findPerson(char *lastName, PERSON &p) appears to search the people array (treating it like an array of PERSON) for a name that matches and assigns to p from the PERSON array. As long as you are aware that at the point of that assignment, the contents of whatever were passed in as 'p' have been overwritten with a copy of the record found, everything is fine. I just wanted to make sure you understood how it works.

as far as code like:

cout << "Enter First Name " << endl;
				cin >> p.fName;
				cout << "Enter last Name " << endl;
				cin >> p.lName;
				cout << "Enter Address " << endl;
				cin >> p.Address;

where p is an instance of PERSON, it is generally not allowed.
Your options are:
1) make the members public. (bad form, but you could make it work.)
2) add accessors for the dataitems. Methods like setFName(char const * fname) that will allow you to set the data members. You would have to accept user input into temporary variables and then call the accessor to set the data.
3) add an update that takes all of the fields that might be updated in one call. (Similar to the previous, you still need to use temporary variables.)
4) add a method that would prompt for and accept input into the members. (I think you said you couldn't do that, but I don't know if it was because you couldn't make it work, or if it was not permitted.)

#2 tends to be the most common implementation.

On one more design note, it looks like you had PERSON and then attempted to add an array to it to make the address book.

I would recommend having an ADDRESSBOOK class that has the array and the members for updating and accessing the PERSON objects in the ADDRESSBOOK.

I apologize for the errors concerning people. I only recently found out that I had to include it in the private variables section. This is also my first class, so please bear with me. Now, as for your suggestion, I think #2 is the only one I would be able to do. 1 and 4 are out of the question as my professor does not like cout or cin in any function besides main. How would I begin to implement this? We learned pointers the week before last, so its not my strong point, but I think I could do it. If I am correctly interpreting what you are saying, this plan would be to make different variables for every variable in the private section of the class.

The array was originally global. I had to put it inside of the class and I have not figured out how to change the rest of the program respectively.

I think you understand the concept. Here's your PERSON class (without the people array) but with some accessors added.

class PERSON
{
private:
	char fName[25];
	char lName[25];
	char Address[100];

public:
	PERSON();
	char const * getFName() const;
	char const * getLName() const;
	char const * getAddress() const;
	void setFName(char const * fname);
	void setLName(char const * lname);
	void setAddress(char const * address);
};

Here's an example implementation for a couple of those methods I added:

char const * PERSON::getFName() const
{
	return fName;
}
void PERSON::setFName(char const * _fname)
{
	strcpy_s(fName, sizeof(fName), _fname);
}

then the calls from main to reference the new methods:

case ADDPERSON :
				
				cout << "Enter First Name " << endl;
				cin >> fName;
				cout << "Enter last Name " << endl;
				cin >> lName;
				cout << "Enter Address " << endl;
				cin >> Address;

				p.setFName(fName);
				p.setLName(lName);
				p.setAddress(Address);

				status = access.addPerson(p);

You already had character buffers for the fName, lName and Address declared.

Thank you for your demonstration, this is helpful. I am curious, is this some kind of a constant character pointer? Wouldn't it need to be an array? I don't know very much about this, but it seems to me that a pointer won't hold anything; it will just point to an address...

Yes the getFName did return a constant character pointer. All pointers can implicitly be treated as an array (you just have to be careful not to write where you don't have permission). In this case, it points to the buffer inside the PERSON object and is a pointer to a const char. (The const part encourages the compiler to make it hard for you to write through the pointer accidentally.) You can use this pointer in your code like you would any character array. (Specifically, you can cout << p.getFName(); and will output the first name, just like you might expect it to.)

We don't really need to make a copy of the string unless we plan to modify it. And if we do, we can make the copy using the pointer.

The same thing works in reverse for the setFName() method, except the only thing we do with the pointer is to make a copy of what it pointed to into our buffer.

Thank you, I understand. This was very helpful. I believe that I have all the information that I need to finish my project. I truly appreciate your explanation.

please send the whole correct code .

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.