Solved

Reading/Writing array of structs from binary

Posted on 2007-12-03
19
642 Views
Last Modified: 2010-04-21
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

0
Comment
Question by:pacman32689
  • 11
  • 4
  • 4
19 Comments
 

Author Comment

by:pacman32689
ID: 20400130
Bump? :)
0
 

Author Comment

by:pacman32689
ID: 20400150
I was thinking something along the lines of...




while(getline(fileData,str))

	{

            // char array accepting all information seperated by & and : 

        }

Open in new window

0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 300 total points
ID: 20401462
If thinking on a binary file you simply can use ifstream::read and ofstream::write:


bool writeToFile(contactParameter contact[], int n, const char* szFilename)
{
       ofstream ofs(szFilename, ios::out | ios::binary);
       if (!ofs)
       {
            cout << szFilename << " couldn't be opened ' << endl;
            return false;
       }
       for (int i = 0; i < n; ++n)
       {
             ofs.write((const char*)&contact[i], sizeof(contactParameter));      
       }
       ofs.close();  
       return true;    
}

The read is similar, only using ifstream and ios::in

int readFromFile(contactParameter contact[], int siz, const char* szFilename)
{
       ifstream ifs(szFilename, ios::in | ios::binary);
       if (!ifs)
       {
            cout << szFilename << " couldn't be opened ' << endl;
            return -1;
       }
       int i = 0;
       while (i < siz && ifs.read((char*)&contact[i], sizeof(contactParameter)))
            i++;
       ifs.close();  
       return i;    
}

Regards, Alex
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 20401570
>> 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 !
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20401750
>>>> 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

0
 

Author Comment

by:pacman32689
ID: 20407659
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?
0
 

Author Comment

by:pacman32689
ID: 20408072
For some reason I can't post my code anymore? Is something going on?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20409466
>>>> 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
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20409495
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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:pacman32689
ID: 20409721
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!
0
 

Author Comment

by:pacman32689
ID: 20415285
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

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 20415292
>> I am getting two errors that it is expecting a primary expression.

Where ?
0
 

Author Comment

by:pacman32689
ID: 20415374
below case 6: in the menu array and the readData in main()
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 20415405
     readData(contact, fileName);

instead of :

      readData(contact[250], fileName);

Similar elsewhere.
0
 

Author Comment

by:pacman32689
ID: 20415469
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

0
 

Author Comment

by:pacman32689
ID: 20415470
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

0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 200 total points
ID: 20415480
>> mm it is now telling me it cannot convert string to char for arguement 2

Well, the error is pretty straightforward, no ? You're trying to pass a string, where the function expects a char*

Use fileName.c_str()
0
 

Author Comment

by:pacman32689
ID: 20415544
d'oh thanks. I have had a very long week :)
0
 

Author Closing Comment

by:pacman32689
ID: 31412477
thanks!
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now