Link to home
Start Free TrialLog in
Avatar of pacman32689
pacman32689

asked on

Reading/Writing array of structs from binary

Hi guys. For my address book program I am storing everything in structs. I need to write the subsequent changes in the array of structs to a file. I am wondering how this is done considering I have never written an array of structs to a binary file before.

 I was wondering if I could use the same strategy I used on an older program. Members of a struct would be seperated by ':'s while structs in the array would be seperated by '&'s. Does this sound ok? This is my first time writing to a file. Thanks for the help!
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
 
 
using namespace std;
 
 
 
void addContact(int counter);
void updateContact();
void deleteContact();
void printContacts();
void searchContact();
void menu();
int findFreeSpot();
 
struct birthdate
	{
		int date;
		int month;
		int year;
	};
	struct contactParameter
	{
		char name[50];
		char cellPhoneNumber[50];
		char emailAddress[50];
		birthdate birthday;	
		bool validData;
		enum personalOrBusiness
		{
			personal,
			business
		};
		personalOrBusiness pOrBType;
		
	};	
	contactParameter contact[250];
	contactParameter tempContactHolder[10];
	
int main()
{
	string str;
	string fileName;
	
	fstream fileData;
	
	cout << "Please enter the name of the file holding your address book.\n\n";
	getline(cin,fileName);
	fileData.open(fileName.c_str(), ios::in | ios::binary);
	while (true)  // infinite loop to keep returning to menu	
	{
		menu();
	}
}	
void menu()
{	
	string str;
	int menuChoice;
	findFreeSpot();
	cout << "Welcome to the address book application. Please select a task from the menu.\n\n"
		 << "1) Add a new contact \n\n2) Update a contact's informantion \n\n3) Delete a contact \n\n"
		 << "4) Search for a contact by name or address \n\n5) Print personal or business contacts in"
		 << " alphabetical order by name\n\n6) Exit the Program\n\n"; 
	 getline (cin,str);
	 menuChoice = atoi (str.c_str());
	 
	 switch(menuChoice)
	 {
		case 1:
			addContact(findFreeSpot());
			break;
		case 2:
			updateContact();
			break;
		case 3:
			deleteContact();
			break;
		case 4:
			searchContact();
			break;
		case 5:
			printContacts();
			break;
		case 6:
			
			exit(1);
			break;
		default:
			cout << "You have entered an invalid choice, please enter a valid integer based on your menu choice.";
			break;
	 }
	 
}
 
 
int findFreeSpot()
{
      for(int i = 0; i< 250; i++)
      {
            if(!contact[i].validData)
            {
                  return i;
 
            }
      }
}
 
void addContact(int counter)
{
	char type;
	string str;
	int integer;
	
	cout << "To create a contact, enter the appropriate information as you are prompted. If you are unsure of something,"
	     << " just enter a -1.\n\n";
	cout << "Name?\n\n";
	getline (cin,str);
	strncpy(contact[counter].name, str.c_str(), sizeof(contact[counter].name) - 1);
	contact[counter].name[sizeof(contact[counter].name) - 1] = '\0';
	cout << "Cellphone number?\n\n";
	getline (cin,str);
	strncpy(contact[counter].cellPhoneNumber, str.c_str(), sizeof(contact[counter].cellPhoneNumber) - 1);
	contact[counter].cellPhoneNumber[sizeof(contact[counter].cellPhoneNumber) - 1] = '\0';
	cout << "Email address?\n\n";
	getline (cin,str);
	strncpy(contact[counter].emailAddress, str.c_str(), sizeof(contact[counter].emailAddress) - 1);
	contact[counter].emailAddress[sizeof(contact[counter].emailAddress) - 1] = '\0';
	cout << "Birthday day?\n\n";
	getline (cin,str);
	integer = atoi (str.c_str());
	integer = contact[counter].birthday.date;
	cout << "Birthday month (number)?\n\n";
	getline (cin,str);
	integer = atoi (str.c_str());
	integer = contact[counter].birthday.month;
	cout << "Birthday year?\n\n";
	getline (cin,str);
	integer = atoi(str.c_str());
	integer= contact[counter].birthday.year;
	do
	{
		cout << "Contact type is (P)ersonal or (B)usiness?\n\n";
		cin >> type;
	}while(type!='P' && type!='B');
	contact[counter].pOrBType = (type =='P' ? contactParameter::personal : contactParameter::business);      
	contact[counter].validData = true;  
	
}
 
void updateContact()
{
	string str;
	int integer;
	int tempModify, modifyMember;
	
	for(int i = 0; i < 250; i++)
	{
		if(contact[i].validData == true)
		{
			cout << i << " " << contact[i].name << "\n\n";
		}
	}
	cout << "Please enter the number of the contact you wish to modify.\n\n";
	getline(cin,str);
	tempModify = atoi (str.c_str());
	cout << "Enter '1' to modify name.\n\nEnter '2' to modify cell phone number.\n\nEnter '3' to modify e-mail address\n\nEnter '4' to modify birthday date\n\nEnter '5' to modify birthday month\n\nEnter "
		 << "'6' to modify birthday year\n\nEnter '7' to modify contact type.\n\n";
	getline(cin,str);
	modifyMember = atoi (str.c_str());
	switch(modifyMember)
	{
		case 1:
			cout << "Name?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].name, str.c_str(), sizeof(contact[tempModify].name) - 1);
			contact[tempModify].name[sizeof(contact[tempModify].name) - 1] = '\0';
			break;
		case 2:
			cout << "Cellphone number?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].cellPhoneNumber, str.c_str(), sizeof(contact[tempModify].cellPhoneNumber) - 1);
			contact[tempModify].cellPhoneNumber[sizeof(contact[tempModify].cellPhoneNumber) - 1] = '\0';
			break;
		case 3:
			cout << "Email address?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].emailAddress, str.c_str(), sizeof(contact[tempModify].emailAddress) - 1);
			contact[tempModify].emailAddress[sizeof(contact[tempModify].emailAddress) - 1] = '\0';
			break;
		case 4:
			cout <<"Birthday day? (number)?\n\n";
			getline (cin,str);
			integer = atoi (str.c_str());
			integer = contact[tempModify].birthday.date;
			break;
 
		case 5:
			cout << "Birthday month (number)?\n\n";
			getline (cin,str);
			integer = atoi (str.c_str());
			integer = contact[tempModify].birthday.month;
			break;
		case 6:
			cout << "Birthday year?\n\n";
			getline (cin,str);
			integer = atoi(str.c_str());
			integer= contact[tempModify].birthday.year;	
			break;
		case 7:
			char type;
			do
			{
				cout << "Contact type is (P)ersonal or (B)usiness?\n\n";
				cin >> type;
			}while(type!='P' && type!='B');
			contact[tempModify].pOrBType = (type =='P' ? contactParameter::personal : contactParameter::business); 
			break;
		default:
			cout << "You have entered an invalid choice, please enter a valid integer based on your choice.";
			updateContact();
			break;
 
	}		
 
}
 
void deleteContact()	
{
	string str;
	int numDelete;
	for(int i = 0; i < 250; i++)
	{
		if(contact[i].validData == true)
		{
			cout << i << " " << contact[i].name << "\n\n";
		}
	}
	cout << "Please enter the number of the contact you wish to delete.\n\n";
	getline(cin,str);
	numDelete = atoi (str.c_str());
	contact[numDelete].validData = false;
}
 
void searchContact()
{
	
	int temp;
	string str;
	
	while(temp!= 0 || temp!= 1)
	{
		cout << "Please enter a '0' if you are searching by name or a '1' if you are searching by e-mail address\n\n";
		getline (cin,str);
		temp = atoi (str.c_str());
	}
	if(temp == 0)
	{
		cout << "Please enter the name you are looking for.\n\n";
		getline (cin,str);
		
		for(int i =0; i < 250; i++)
		{
			if(strcmp(contact[i].name,str.c_str()) == 0)
			{
				cout << "Name: " << contact[i].name << "\n\nemail adress: " << contact[i].emailAddress << "\n\ncell phone number: " <<contact[i].cellPhoneNumber
					 << "\n\nbirth date:  "<< contact[i].birthday.date << "\n\nbirth month: " << contact[i].birthday.month << "\n\nbirth year: " << contact[i].birthday.year
					 << "\n\ncontact type: " << contact[i].pOrBType;
			}
			else
			{
				cout<< "\n\nEntry not found or end of search\n\n";
			}
		}	
			
	}
	if(temp == 1)
	{
		cout << "Please enter the e-mail address you are looking for.\n\n";
		getline (cin,str);
		
		for(int i =0; i < 250; i++)
		{
			if(strcmp(contact[i].emailAddress,str.c_str()) == 0)
			{
				cout << "Name: " << contact[i].name << "\n\nemail adress: " << contact[i].emailAddress << "\n\ncell phone number: " <<contact[i].cellPhoneNumber
					 << "\n\nbirth date:  "<< contact[i].birthday.date << "\n\nbirth month: " << contact[i].birthday.month << "\n\nbirth year: " << contact[i].birthday.year
					 << "\n\ncontact type: " << contact[i].pOrBType;
			}
			else
			{
				cout<< "\n\nEntry not found or end of search\n\n";
			}
		}	
			
	}
		
}
 
void printContacts()
{
	int tempPrint;
	string str;
	bool swapped = true;
	
	do	{
			cout << "Please enter 0 if you would like to view personal contacts or 1 if you would like to view business contacts.\n\n";
//			getline(cin,str);
//			tempPrint = atoi (str.c_str());
			cin >> tempPrint;
	}while(tempPrint!= 0 && tempPrint!= 1);
 
	 
	if(tempPrint == 0)
	{
		do
		{
			swapped = false;
			for(int i = 0; i < 250; i++)
			{
				if( strcmp(contact[i].name,contact[i+1].name) < 0 && contact[i].pOrBType == 0)
				{
					swapped = true;
					contact[i] = tempContactHolder[i];
					contact[i] = contact[i+1];
					contact[i+1] = tempContactHolder[i]; 
					
				}
			}
		}
		while(swapped);
		
		for(int i = 0; i <250; i++)
		{
			if( contact[i].validData == true)
			{
				cout << "Name: " << contact[i].name << "\n\nCell Phone Number: " << contact[i].cellPhoneNumber << "\n\nemail address: " << contact[i].emailAddress;
				if(contact[i].birthday.date != -1)
				{
					cout<< "\n\nBirthday: " << contact[i].birthday.date << " " << contact[i].birthday.month << " " << contact[i].birthday.year;
				}
			}
		}
	}
	if(tempPrint == 1)
	{
		cout << "Business!";
		swapped = true;
		do
		{
			swapped = false;
			for(int i = 0; i < 250; i++)
			{
				if( strcmp(contact[i].name,contact[i+1].name) < 0 && contact[i].pOrBType == 1)
				{
					swapped = true;
					contact[i] = tempContactHolder[i];
					contact[i] = contact[i+1];
					contact[i+1] = tempContactHolder[i]; 
					
				}
			}
		}
		while(swapped);
		
		for(int i = 0; i <250; i++)
		{
			if( contact[i].validData == true)
			{
				cout << i << " Name: " << contact[i].name << "\n\nCell Phone Number: " << contact[i].cellPhoneNumber << "\n\nemail address: " << contact[i].emailAddress;
				if(contact[i].birthday.date != -1)
				{
					cout<< "\n\nBirthday: " << contact[i].birthday.date << " " << contact[i].birthday.month << " " << contact[i].birthday.year;
				}
			}
		}
	}
 
}

Open in new window

Avatar of pacman32689
pacman32689

ASKER

Bump? :)
I was thinking something along the lines of...



while(getline(fileData,str))
	{
            // char array accepting all information seperated by & and : 
        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of itsmeandnobodyelse
itsmeandnobodyelse
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Infinity08
>> Members of a struct would be seperated by ':'s while structs in the array would be seperated by '&'s. Does this sound ok?

That would be ok for a text file, but you want a binary file. The easiest way is to just put the exact memory contents in the file using write (as Alex said), and when you need to get it from the file again, you can simply use read (see Alex's post).

This technique will only be reliable if the executable that is reading the file is the same  as the one that wrote the file !
>>>> Members of a struct would be seperated by ':'s
>>>> while structs in the array would be seperated by '&'s.
>>>> Does this sound ok?

The technique is called serializing. It is much more efforts and you have to find separators that definitively do not occur in the data. E. g. the colon ':' may occur in a time value "11:20" or the ampersand '&' in a company name. You have to 'escape' these character then *or* use a special sign like '°' or a tricky sequence "#|#". There is another method which is simpler to parse: a record containing one struct begins with the total length of the stored data and each data field was preceeded by it's length as well:

72 11 John Smith 11 123-456-789 11 xyz@abc.com 10 01/02/1979 4 true 4 true

Here a parser would read the line, would extract the 72 and 'knows' the length of the following data. Then extract the 11 and knows the length of the name, and so on.

You see it is not difficult but writing/reading binary data is much easier though - as Infiniity already told, binary data often cannot be transferred between platforms or even between programs. There may be different alignments or character sets, though the latter may also happen with pure text data. Alignment is the method members were 'aligned' within a struct. It mostly defaults to 4-byte or 8-byte alignment waht means that a struct member within a struct (e. g. birthday in your code) was set to an offset which is a multiple of 4 respectively 8 calculated from the start address of the parent struct. So 'birthday' would be aligned to offset 152 (and not 150) and there is a gap of two bytes between the email and the birthday. Another program may have 1-byte alignment and has no gap because of that.

An alternative to both binary or text maybe is XML. You would store the data like

<?xml version="1.0" ?>
<contactParameter name="John Smith" phone="123-456-789" email="xyz@abc.com" birthday="01/02/1979" valid="true" business="false" />

For that there are cillions of libraries (and private parsers) which were able to read and write the above xml file.

Regards, Alex

Thanks so far guys. It appears a counter named 'i' is being used to increment each struct read in. (?) However, how would I find the size of the file so that I would be able to use the counter properly?
For some reason I can't post my code anymore? Is something going on?
>>>> However, how would I find the size of the file so that I would be able to use the counter properly?

You can get it by means of the stat function:

...
#include <sys/stat.h>
....


      struct stat fs;
      if (stat(szFilename, &fs) != 0)
      {
             // error file not found
             return false;
      }
      int filesize = fs.st_size;
     
      // in case of a binary file we can calculate the number of records
      int nrecs = filesize/sizeof(contactParameter);

Regards, Alex
If you have a text file you can get the size but not the number of lines by the above method.

You should consider a dynamic array to store your structures. A dynamic array can grow dynamically, so you could read record by record or line by line and add a new entry to the array:

#include <vector>
using namespace std;
    ....
    vector<contactParameter> allcontacts;
    contactParameter cp;
    while (ifs.read((char*)&cp, sizeof(cp)))
    {
           allcontacts.push_back(cp);  // add rec to array
    }

You can make the allcontacts a static member of class contactParameter.
If I just the need the size of the file to put it into a binary file I should be fine, I will work on implementing some changes and get back to you, thanks!
I am getting two errors that it is expecting a primary expression.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
 
 
using namespace std;
 
struct birthdate
	{
		int date;
		int month;
		int year;
	};
struct contactParameter
{
	char name[50];
	char cellPhoneNumber[50];
	char emailAddress[50];
	birthdate birthday;	
	bool validData;
	enum personalOrBusiness
	{
		personal,
		business
	};
	personalOrBusiness pOrBType;
		
};	
contactParameter contact[250];
contactParameter tempContactHolder[10];
 
void addContact(int counter);
void updateContact();
void deleteContact();
void printContacts();
void searchContact();
void menu();
int readData(contactParameter contact[], const char* szFilename);
bool writeData(contactParameter contact[], const char* szFilename);
int findFreeSpot();
 
	
int main()
{
	string str;
	string fileName;
	fstream myFile("filename", ios::in | ios::binary);
	readData(contact[250], fileName);
	
	cout << "Please enter the name of the file holding your address book.\n\n";
	getline(cin,fileName);
 
		  
		
		
	while (true)  // infinite loop to keep returning to menu	
	{
		menu();
	}
}	
 
int readData(contactParameter contact[], const char* szFilename)
{
	ifstream ifs("filename",ios::in | ios::binary);
	int i = 0;
	while( i < 250 && ifs.read((char*)&contact[i], sizeof(contactParameter)))
	{
		i++;
	}
	ifs.close();
	return i;
	
}
bool writeData(contactParameter contact[], const char* szFilename)
{
	ofstream ofs("filename", ios::out | ios:: binary);
	for(int i = 0; i < 250 ; i++)
	{
		ofs.write((const char*)&contact[i], sizeof(contactParameter));
	}
	ofs.close();
	return true;
}	
void menu()
{	
	string str, filename;
	int menuChoice;
	findFreeSpot();
	cout << "Welcome to the address book application. Please select a task from the menu.\n\n"
		 << "1) Add a new contact \n\n2) Update a contact's informantion \n\n3) Delete a contact \n\n"
		 << "4) Search for a contact by name or address \n\n5) Print personal or business contacts in"
		 << " alphabetical order by name\n\n6) Exit the Program\n\n"; 
	 getline (cin,str);
	 menuChoice = atoi (str.c_str());
	 
	 switch(menuChoice)
	 {
		case 1:
			addContact(findFreeSpot());
			break;
		case 2:
			updateContact();
			break;
		case 3:
			deleteContact();
			break;
		case 4:
			searchContact();
			break;
		case 5:
			printContacts();
			break;
		case 6:
	
			writeData(contact[250],"fileName.txt");
			exit(1);
			break;
		default:
			cout << "You have entered an invalid choice, please enter a valid integer based on your menu choice.";
			break;
	 }
	 
}
 
 
int findFreeSpot()
{
      for(int i = 0; i< 250; i++)
      {
            if(!contact[i].validData)
            {
                  return i;
 
            }
      }
}
 
void addContact(int counter)
{
	char type;
	string str;
	int integer;
	
	cout << "To create a contact, enter the appropriate information as you are prompted. If you are unsure of something,"
	     << " just enter a -1.\n\n";
	cout << "Name?\n\n";
	getline (cin,str);
	strncpy(contact[counter].name, str.c_str(), sizeof(contact[counter].name) - 1);
	contact[counter].name[sizeof(contact[counter].name) - 1] = '\0';
	cout << "Cellphone number?\n\n";
	getline (cin,str);
	strncpy(contact[counter].cellPhoneNumber, str.c_str(), sizeof(contact[counter].cellPhoneNumber) - 1);
	contact[counter].cellPhoneNumber[sizeof(contact[counter].cellPhoneNumber) - 1] = '\0';
	cout << "Email address?\n\n";
	getline (cin,str);
	strncpy(contact[counter].emailAddress, str.c_str(), sizeof(contact[counter].emailAddress) - 1);
	contact[counter].emailAddress[sizeof(contact[counter].emailAddress) - 1] = '\0';
	cout << "Birthday day?\n\n";
	getline (cin,str);
	integer = atoi (str.c_str());
	integer = contact[counter].birthday.date;
	cout << "Birthday month (number)?\n\n";
	getline (cin,str);
	integer = atoi (str.c_str());
	integer = contact[counter].birthday.month;
	cout << "Birthday year?\n\n";
	getline (cin,str);
	integer = atoi(str.c_str());
	integer= contact[counter].birthday.year;
	do
	{
		cout << "Contact type is (P)ersonal or (B)usiness?\n\n";
		cin >> type;
	}while(type!='P' && type!='B');
	contact[counter].pOrBType = (type =='P' ? contactParameter::personal : contactParameter::business);      
	contact[counter].validData = true;  
	
}
 
void updateContact()
{
	string str;
	int integer;
	int tempModify, modifyMember;
	
	for(int i = 0; i < 250; i++)
	{
		if(contact[i].validData == true)
		{
			cout << i << " " << contact[i].name << "\n\n";
		}
	}
	cout << "Please enter the number of the contact you wish to modify.\n\n";
	getline(cin,str);
	tempModify = atoi (str.c_str());
	cout << "Enter '1' to modify name.\n\nEnter '2' to modify cell phone number.\n\nEnter '3' to modify e-mail address\n\nEnter '4' to modify birthday date\n\nEnter '5' to modify birthday month\n\nEnter "
		 << "'6' to modify birthday year\n\nEnter '7' to modify contact type.\n\n";
	getline(cin,str);
	modifyMember = atoi (str.c_str());
	switch(modifyMember)
	{
		case 1:
			cout << "Name?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].name, str.c_str(), sizeof(contact[tempModify].name) - 1);
			contact[tempModify].name[sizeof(contact[tempModify].name) - 1] = '\0';
			break;
		case 2:
			cout << "Cellphone number?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].cellPhoneNumber, str.c_str(), sizeof(contact[tempModify].cellPhoneNumber) - 1);
			contact[tempModify].cellPhoneNumber[sizeof(contact[tempModify].cellPhoneNumber) - 1] = '\0';
			break;
		case 3:
			cout << "Email address?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].emailAddress, str.c_str(), sizeof(contact[tempModify].emailAddress) - 1);
			contact[tempModify].emailAddress[sizeof(contact[tempModify].emailAddress) - 1] = '\0';
			break;
		case 4:
			cout <<"Birthday day? (number)?\n\n";
			getline (cin,str);
			integer = atoi (str.c_str());
			integer = contact[tempModify].birthday.date;
			break;
 
		case 5:
			cout << "Birthday month (number)?\n\n";
			getline (cin,str);
			integer = atoi (str.c_str());
			integer = contact[tempModify].birthday.month;
			break;
		case 6:
			cout << "Birthday year?\n\n";
			getline (cin,str);
			integer = atoi(str.c_str());
			integer= contact[tempModify].birthday.year;	
			break;
		case 7:
			char type;
			do
			{
				cout << "Contact type is (P)ersonal or (B)usiness?\n\n";
				cin >> type;
			}while(type!='P' && type!='B');
			contact[tempModify].pOrBType = (type =='P' ? contactParameter::personal : contactParameter::business); 
			break;
		default:
			cout << "You have entered an invalid choice, please enter a valid integer based on your choice.";
			updateContact();
			break;
 
	}		
 
}
 
void deleteContact()	
{
	string str;
	int numDelete;
	for(int i = 0; i < 250; i++)
	{
		if(contact[i].validData == true)
		{
			cout << i << " " << contact[i].name << "\n\n";
		}
	}
	cout << "Please enter the number of the contact you wish to delete.\n\n";
	getline(cin,str);
	numDelete = atoi (str.c_str());
	contact[numDelete].validData = false;
}
 
void searchContact()
{
	
	int temp;
	string str;
	
	while(temp!= 0 || temp!= 1)
	{
		cout << "Please enter a '0' if you are searching by name or a '1' if you are searching by e-mail address\n\n";
		getline (cin,str);
		temp = atoi (str.c_str());
	}
	if(temp == 0)
	{
		cout << "Please enter the name you are looking for.\n\n";
		getline (cin,str);
		
		for(int i =0; i < 250; i++)
		{
			if(strcmp(contact[i].name,str.c_str()) == 0)
			{
				cout << "Name: " << contact[i].name << "\n\nemail adress: " << contact[i].emailAddress << "\n\ncell phone number: " <<contact[i].cellPhoneNumber
					 << "\n\nbirth date:  "<< contact[i].birthday.date << "\n\nbirth month: " << contact[i].birthday.month << "\n\nbirth year: " << contact[i].birthday.year
					 << "\n\ncontact type: " << contact[i].pOrBType;
			}
			else
			{
				cout<< "\n\nEntry not found or end of search\n\n";
			}
		}	
			
	}
	if(temp == 1)
	{
		cout << "Please enter the e-mail address you are looking for.\n\n";
		getline (cin,str);
		
		for(int i =0; i < 250; i++)
		{
			if(strcmp(contact[i].emailAddress,str.c_str()) == 0)
			{
				cout << "Name: " << contact[i].name << "\n\nemail adress: " << contact[i].emailAddress << "\n\ncell phone number: " <<contact[i].cellPhoneNumber
					 << "\n\nbirth date:  "<< contact[i].birthday.date << "\n\nbirth month: " << contact[i].birthday.month << "\n\nbirth year: " << contact[i].birthday.year
					 << "\n\ncontact type: " << contact[i].pOrBType;
			}
			else
			{
				cout<< "\n\nEntry not found or end of search\n\n";
			}
		}	
			
	}
		
}
 
void printContacts()
{
	int tempPrint;
	string str;
	bool swapped = true;
	
	do	{
			cout << "Please enter 0 if you would like to view personal contacts or 1 if you would like to view business contacts.\n\n";
//			getline(cin,str);
//			tempPrint = atoi (str.c_str());
			cin >> tempPrint;
	}while(tempPrint!= 0 && tempPrint!= 1);
 
	 
	if(tempPrint == 0)
	{
		do
		{
			swapped = false;
			for(int i = 0; i < 250; i++)
			{
				if( strcmp(contact[i].name,contact[i+1].name) < 0 && contact[i].pOrBType == 0)
				{
					swapped = true;
					contact[i] = tempContactHolder[i];
					contact[i] = contact[i+1];
					contact[i+1] = tempContactHolder[i]; 
					
				}
			}
		}
		while(swapped);
		
		for(int i = 0; i <250; i++)
		{
			if( contact[i].validData == true)
			{
				cout << "Name: " << contact[i].name << "\n\nCell Phone Number: " << contact[i].cellPhoneNumber << "\n\nemail address: " << contact[i].emailAddress;
				if(contact[i].birthday.date != -1)
				{
					cout<< "\n\nBirthday: " << contact[i].birthday.date << " " << contact[i].birthday.month << " " << contact[i].birthday.year;
				}
			}
		}
	}
	if(tempPrint == 1)
	{
		cout << "Business!";
		swapped = true;
		do
		{
			swapped = false;
			for(int i = 0; i < 250; i++)
			{
				if( strcmp(contact[i].name,contact[i+1].name) < 0 && contact[i].pOrBType == 1)
				{
					swapped = true;
					contact[i] = tempContactHolder[i];
					contact[i] = contact[i+1];
					contact[i+1] = tempContactHolder[i]; 
					
				}
			}
		}
		while(swapped);
		
		for(int i = 0; i <250; i++)
		{
			if( contact[i].validData == true)
			{
				cout << i << " Name: " << contact[i].name << "\n\nCell Phone Number: " << contact[i].cellPhoneNumber << "\n\nemail address: " << contact[i].emailAddress;
				if(contact[i].birthday.date != -1)
				{
					cout<< "\n\nBirthday: " << contact[i].birthday.date << " " << contact[i].birthday.month << " " << contact[i].birthday.year;
				}
			}
		}
	}
 
}

Open in new window

>> I am getting two errors that it is expecting a primary expression.

Where ?
below case 6: in the menu array and the readData in main()
     readData(contact, fileName);

instead of :

      readData(contact[250], fileName);

Similar elsewhere.
mm it is now telling me it cannot convert string to char for arguement 2
mm it is now telling me it cannot convert string to char for arguement 2

Open in new window

sorry!
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
 
 
using namespace std;
 
struct birthdate
	{
		int date;
		int month;
		int year;
	};
struct contactParameter
{
	char name[50];
	char cellPhoneNumber[50];
	char emailAddress[50];
	birthdate birthday;	
	bool validData;
	enum personalOrBusiness
	{
		personal,
		business
	};
	personalOrBusiness pOrBType;
		
};	
contactParameter contact[250];
contactParameter tempContactHolder[10];
 
void addContact(int counter);
void updateContact();
void deleteContact();
void printContacts();
void searchContact();
void menu();
int readData(contactParameter contact[], const char* szFilename);
bool writeData(contactParameter contact[], const char* szFilename);
int findFreeSpot();
 
	
int main()
{
	string str;
	string fileName;
	fstream myFile("filename", ios::in | ios::binary);
	readData(contact, fileName);
	
	cout << "Please enter the name of the file holding your address book.\n\n";
	getline(cin,fileName);
 
		  
		
		
	while (true)  // infinite loop to keep returning to menu	
	{
		menu();
	}
}	
 
int readData(contactParameter contact[], const char* szFilename)
{
	ifstream ifs("filename",ios::in | ios::binary);
	int i = 0;
	while( i < 250 && ifs.read((char*)&contact[i], sizeof(contactParameter)))
	{
		i++;
	}
	ifs.close();
	return i;
	
}
bool writeData(contactParameter contact[], const char* szFilename)
{
	ofstream ofs("filename", ios::out | ios:: binary);
	for(int i = 0; i < 250 ; i++)
	{
		ofs.write((const char*)&contact[i], sizeof(contactParameter));
	}
	ofs.close();
	return true;
}	
void menu()
{	
	string str, fileName;
	int menuChoice;
	findFreeSpot();
	cout << "Welcome to the address book application. Please select a task from the menu.\n\n"
		 << "1) Add a new contact \n\n2) Update a contact's informantion \n\n3) Delete a contact \n\n"
		 << "4) Search for a contact by name or address \n\n5) Print personal or business contacts in"
		 << " alphabetical order by name\n\n6) Exit the Program\n\n"; 
	 getline (cin,str);
	 menuChoice = atoi (str.c_str());
	 
	 switch(menuChoice)
	 {
		case 1:
			addContact(findFreeSpot());
			break;
		case 2:
			updateContact();
			break;
		case 3:
			deleteContact();
			break;
		case 4:
			searchContact();
			break;
		case 5:
			printContacts();
			break;
		case 6:
			cout << "Please enter name for the new file.\n\n";
		
	
			writeData(contact, fileName);
			exit(1);
			break;
		default:
			cout << "You have entered an invalid choice, please enter a valid integer based on your menu choice.";
			break;
	 }
	 
}
 
 
int findFreeSpot()
{
      for(int i = 0; i< 250; i++)
      {
            if(!contact[i].validData)
            {
                  return i;
 
            }
      }
}
 
void addContact(int counter)
{
	char type;
	string str;
	int integer;
	
	cout << "To create a contact, enter the appropriate information as you are prompted. If you are unsure of something,"
	     << " just enter a -1.\n\n";
	cout << "Name?\n\n";
	getline (cin,str);
	strncpy(contact[counter].name, str.c_str(), sizeof(contact[counter].name) - 1);
	contact[counter].name[sizeof(contact[counter].name) - 1] = '\0';
	cout << "Cellphone number?\n\n";
	getline (cin,str);
	strncpy(contact[counter].cellPhoneNumber, str.c_str(), sizeof(contact[counter].cellPhoneNumber) - 1);
	contact[counter].cellPhoneNumber[sizeof(contact[counter].cellPhoneNumber) - 1] = '\0';
	cout << "Email address?\n\n";
	getline (cin,str);
	strncpy(contact[counter].emailAddress, str.c_str(), sizeof(contact[counter].emailAddress) - 1);
	contact[counter].emailAddress[sizeof(contact[counter].emailAddress) - 1] = '\0';
	cout << "Birthday day?\n\n";
	getline (cin,str);
	integer = atoi (str.c_str());
	integer = contact[counter].birthday.date;
	cout << "Birthday month (number)?\n\n";
	getline (cin,str);
	integer = atoi (str.c_str());
	integer = contact[counter].birthday.month;
	cout << "Birthday year?\n\n";
	getline (cin,str);
	integer = atoi(str.c_str());
	integer= contact[counter].birthday.year;
	do
	{
		cout << "Contact type is (P)ersonal or (B)usiness?\n\n";
		cin >> type;
	}while(type!='P' && type!='B');
	contact[counter].pOrBType = (type =='P' ? contactParameter::personal : contactParameter::business);      
	contact[counter].validData = true;  
	
}
 
void updateContact()
{
	string str;
	int integer;
	int tempModify, modifyMember;
	
	for(int i = 0; i < 250; i++)
	{
		if(contact[i].validData == true)
		{
			cout << i << " " << contact[i].name << "\n\n";
		}
	}
	cout << "Please enter the number of the contact you wish to modify.\n\n";
	getline(cin,str);
	tempModify = atoi (str.c_str());
	cout << "Enter '1' to modify name.\n\nEnter '2' to modify cell phone number.\n\nEnter '3' to modify e-mail address\n\nEnter '4' to modify birthday date\n\nEnter '5' to modify birthday month\n\nEnter "
		 << "'6' to modify birthday year\n\nEnter '7' to modify contact type.\n\n";
	getline(cin,str);
	modifyMember = atoi (str.c_str());
	switch(modifyMember)
	{
		case 1:
			cout << "Name?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].name, str.c_str(), sizeof(contact[tempModify].name) - 1);
			contact[tempModify].name[sizeof(contact[tempModify].name) - 1] = '\0';
			break;
		case 2:
			cout << "Cellphone number?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].cellPhoneNumber, str.c_str(), sizeof(contact[tempModify].cellPhoneNumber) - 1);
			contact[tempModify].cellPhoneNumber[sizeof(contact[tempModify].cellPhoneNumber) - 1] = '\0';
			break;
		case 3:
			cout << "Email address?\n\n";
			getline (cin,str);
			strncpy(contact[tempModify].emailAddress, str.c_str(), sizeof(contact[tempModify].emailAddress) - 1);
			contact[tempModify].emailAddress[sizeof(contact[tempModify].emailAddress) - 1] = '\0';
			break;
		case 4:
			cout <<"Birthday day? (number)?\n\n";
			getline (cin,str);
			integer = atoi (str.c_str());
			integer = contact[tempModify].birthday.date;
			break;
 
		case 5:
			cout << "Birthday month (number)?\n\n";
			getline (cin,str);
			integer = atoi (str.c_str());
			integer = contact[tempModify].birthday.month;
			break;
		case 6:
			cout << "Birthday year?\n\n";
			getline (cin,str);
			integer = atoi(str.c_str());
			integer= contact[tempModify].birthday.year;	
			break;
		case 7:
			char type;
			do
			{
				cout << "Contact type is (P)ersonal or (B)usiness?\n\n";
				cin >> type;
			}while(type!='P' && type!='B');
			contact[tempModify].pOrBType = (type =='P' ? contactParameter::personal : contactParameter::business); 
			break;
		default:
			cout << "You have entered an invalid choice, please enter a valid integer based on your choice.";
			updateContact();
			break;
 
	}		
 
}
 
void deleteContact()	
{
	string str;
	int numDelete;
	for(int i = 0; i < 250; i++)
	{
		if(contact[i].validData == true)
		{
			cout << i << " " << contact[i].name << "\n\n";
		}
	}
	cout << "Please enter the number of the contact you wish to delete.\n\n";
	getline(cin,str);
	numDelete = atoi (str.c_str());
	contact[numDelete].validData = false;
}
 
void searchContact()
{
	
	int temp;
	string str;
	
	while(temp!= 0 || temp!= 1)
	{
		cout << "Please enter a '0' if you are searching by name or a '1' if you are searching by e-mail address\n\n";
		getline (cin,str);
		temp = atoi (str.c_str());
	}
	if(temp == 0)
	{
		cout << "Please enter the name you are looking for.\n\n";
		getline (cin,str);
		
		for(int i =0; i < 250; i++)
		{
			if(strcmp(contact[i].name,str.c_str()) == 0)
			{
				cout << "Name: " << contact[i].name << "\n\nemail adress: " << contact[i].emailAddress << "\n\ncell phone number: " <<contact[i].cellPhoneNumber
					 << "\n\nbirth date:  "<< contact[i].birthday.date << "\n\nbirth month: " << contact[i].birthday.month << "\n\nbirth year: " << contact[i].birthday.year
					 << "\n\ncontact type: " << contact[i].pOrBType;
			}
			else
			{
				cout<< "\n\nEntry not found or end of search\n\n";
			}
		}	
			
	}
	if(temp == 1)
	{
		cout << "Please enter the e-mail address you are looking for.\n\n";
		getline (cin,str);
		
		for(int i =0; i < 250; i++)
		{
			if(strcmp(contact[i].emailAddress,str.c_str()) == 0)
			{
				cout << "Name: " << contact[i].name << "\n\nemail adress: " << contact[i].emailAddress << "\n\ncell phone number: " <<contact[i].cellPhoneNumber
					 << "\n\nbirth date:  "<< contact[i].birthday.date << "\n\nbirth month: " << contact[i].birthday.month << "\n\nbirth year: " << contact[i].birthday.year
					 << "\n\ncontact type: " << contact[i].pOrBType;
			}
			else
			{
				cout<< "\n\nEntry not found or end of search\n\n";
			}
		}	
			
	}
		
}
 
void printContacts()
{
	int tempPrint;
	string str;
	bool swapped = true;
	
	do	{
			cout << "Please enter 0 if you would like to view personal contacts or 1 if you would like to view business contacts.\n\n";
//			getline(cin,str);
//			tempPrint = atoi (str.c_str());
			cin >> tempPrint;
	}while(tempPrint!= 0 && tempPrint!= 1);
 
	 
	if(tempPrint == 0)
	{
		do
		{
			swapped = false;
			for(int i = 0; i < 250; i++)
			{
				if( strcmp(contact[i].name,contact[i+1].name) < 0 && contact[i].pOrBType == 0)
				{
					swapped = true;
					contact[i] = tempContactHolder[i];
					contact[i] = contact[i+1];
					contact[i+1] = tempContactHolder[i]; 
					
				}
			}
		}
		while(swapped);
		
		for(int i = 0; i <250; i++)
		{
			if( contact[i].validData == true)
			{
				cout << "Name: " << contact[i].name << "\n\nCell Phone Number: " << contact[i].cellPhoneNumber << "\n\nemail address: " << contact[i].emailAddress;
				if(contact[i].birthday.date != -1)
				{
					cout<< "\n\nBirthday: " << contact[i].birthday.date << " " << contact[i].birthday.month << " " << contact[i].birthday.year;
				}
			}
		}
	}
	if(tempPrint == 1)
	{
		cout << "Business!";
		swapped = true;
		do
		{
			swapped = false;
			for(int i = 0; i < 250; i++)
			{
				if( strcmp(contact[i].name,contact[i+1].name) < 0 && contact[i].pOrBType == 1)
				{
					swapped = true;
					contact[i] = tempContactHolder[i];
					contact[i] = contact[i+1];
					contact[i+1] = tempContactHolder[i]; 
					
				}
			}
		}
		while(swapped);
		
		for(int i = 0; i <250; i++)
		{
			if( contact[i].validData == true)
			{
				cout << i << " Name: " << contact[i].name << "\n\nCell Phone Number: " << contact[i].cellPhoneNumber << "\n\nemail address: " << contact[i].emailAddress;
				if(contact[i].birthday.date != -1)
				{
					cout<< "\n\nBirthday: " << contact[i].birthday.date << " " << contact[i].birthday.month << " " << contact[i].birthday.year;
				}
			}
		}
	}
 
}

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
d'oh thanks. I have had a very long week :)
thanks!