Avanced File I/O

Delete, Changing, and Displaying single c-string records

Page 1 of 1

2 Replies - 595 Views - Last Post: 08 November 2008 - 10:36 AM Rate Topic: -----

#1 SCStudent86  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 06-October 08

Avanced File I/O

Post icon  Posted 07 November 2008 - 09:23 PM

Myself and two others in my class are writing a program that takes in several customer account records from some "bla bla" bank. There should be five options in our program for the user to access.

1. Enter in new record.
2. Display an Individual Record.
3. Delete an Individual Record.
4. Change/Update an Individual Record.
5. Display Contents of Entire File.

Well since we are using, I guess you could say, advance file I/O, my question is HOW THE HECK DO YOU search for an individual c-string records??? It seems very intuitive to just ask the user for the "numeric" record, say 1, and it will display it. However, in the real-world banks do not access individual records in that fashion due to thousands of records. So, so far we have all options defined. Option 3 has not been worked with yet due to the fact its not working correctly. I was thinking of creating a character variable inside option 2, 3, and 4 and apply that variable into seekg, but you can't do that. It goes into a infinite loop. I guess because we are writing into binary format. If you have steady hands you can stop the scroll bar in the command prompt and see the information it spits out right before the infinite loop, hahahaha :D . I know strings have a function to clear every line from beginning to end, but do c-strings have that capability?? Here is our code.

#include<iostream> 
#include<fstream> 
#include<iomanip> 
#include<cctype> 
using namespace std; 
 
const int NAME = 51; 
const int ADDRESS = 51; 
const int HOMETOWN = 51; 
const int TELEPHONE = 14; 
const int LAST_PAYMENT = 11; 
 
struct Account 
{ 
	char name[NAME]; 
	char address[ADDRESS]; 
	char cityStateZip[HOMETOWN]; 
	char teleNumber[TELEPHONE]; 
	char lastPayment[LAST_PAYMENT]; 
	float accountBalance; 
	 
	Account() 
	{ 
		//Empty on purpose 
	}
 
}; 
 
//FUNCTION PROTOTYPES 
void displayMenu(); 
int getChoice(); 
void newRecords(Account&); 
void displayIndividualRecord(Account);
/*void deleteIndividualRecord(Account);*/  
void changeIndividualRecord(Account&);
void displayFile(Account); 

 
int main() 
{ 
	Account information; 
	int option; 
 
	do 
	{ 
		displayMenu(); 
		option = getChoice(); 
 
		switch(option) 
		{ 
			case 1:		newRecords(information); 
						break; 
			 
			case 2:		displayIndividualRecord(information); 
						break; 
 
			/*case 3:		deleteIndividualRecord(information); 
						break;*/ 
		 
			case 4:		changeIndividualRecord(information); 
						break; 
 
			case 5:		displayFile(information); 
						break; 
		} 
	}while(option != 6);
	cout << "Have a nice day!\n\n";
	return 0; 
} 
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************/ 
void displayMenu() 
{ 
	cout << "\n\tWachovia Data Base\n\n"; 
	cout << "1. Enter new records into file.\n"; 
	cout << "2. Display individual record.\n"; 
	cout << "3. Delete individual record.\n"; 
	cout << "4. Change individual record.\n"; 
	cout << "5. Display contents of entire file.\n"; 
	cout << "6. Exit.\n"; 
} 
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************/ 
int getChoice() 
{ 
	int choice; 
 
	cout << "\nWhat option would you like to work with?	"; 
	cin  >> choice; 
	while(choice < 1 || choice > 6) 
	{ 
		cout << "Invalid! Only valid choices are 1-6. Please re-enter.	"; 
		cin  >> choice; 
	} 
	return choice; 
} 
 
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************/ 
void newRecords(Account &customer) 
{ 
	char response; 
 
	//Create file object and open file 
	fstream citizen("DataBase.txt", ios::out | ios::app /*| ios::binary*/); 
 
	//Test for file open error 
	if(!citizen) 
	{ 
		cout << "Error opening file. Shutting down.\n"; 
		exit(0); 
	} 
	do 
	{ 
		//If file opens correctly get information entered by user 
		//and write information to the file in binary mode. 
		cout << "Enter the following information:\n\n"; 
		cout << "Name:					  ";		 
		cin.ignore(); 
		cin.getline(customer.name, NAME); 
		cout << "Address:				   "; 
		cin.getline(customer.address, ADDRESS); 
		cout << "City, State, and Zip:	  "; 
		cin.getline(customer.cityStateZip, HOMETOWN); 
		cout << "Telephone Number:		  "; 
		cin.getline(customer.teleNumber, TELEPHONE); 
		cout << "Account Balance:		   "; 
		cin  >> customer.accountBalance; 
		while(customer.accountBalance < 0.00) 
		{ 
			cout << "Invalid! Customer's account balance must be greater\n" 
				 << "than or equal to $0.00. Please re-enter in customer's\n" 
				 << "account balance:\n"; 
			cin  >> customer.accountBalance; 
		} 
		cout << "Last Payement(mm/dd/yyyy): "; 
		cin.ignore(); 
		cin.getline(customer.lastPayment, LAST_PAYMENT);		 
		citizen.write(reinterpret_cast<char *>(&customer), 
					  sizeof(customer)); 
		cout << "\n\nDo you want to enter in another record(Y/N)?	"; 
		cin  >> response; 
		cin.ignore(); 
	}while(toupper(response) == 'Y'); 
	citizen.close(); 
} 
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************/ 
void displayIndividualRecord(Account customer) 
{ 
	long record; 
 
	//Open file 
	fstream citizen("DataBase.txt", ios::in | ios::binary); 
 
	//Test for file open error 
	if(!citizen) 
	{ 
		cout << "Error opening file. Shutting down.\n"; 
		exit(0); 
	} 
	else 
	{ 
		cout << "\nWhat record would you like to look at?	"; 
		cin  >> record; 
		cout << endl; 
 
		citizen.seekg(record * sizeof(customer), ios::beg); 
		citizen.read(reinterpret_cast<char *>(&customer), sizeof(customer)); 
 
		cout << "\n\nName:					  " << customer.name << endl; 
		cout << "Address:				   " << customer.address << endl; 
		cout << "City, State, and Zip:	  " << customer.cityStateZip << endl; 
		cout << "Telephone Number:		  " << customer.teleNumber << endl; 
		cout << fixed << showpoint << setprecision(2); 
		cout << "Account Balance:		  " << "$" << customer.accountBalance << endl; 
		cout << "Last Payment(mm/dd/yyyy):  " << customer.lastPayment << endl << endl; 
	} 
	citizen.close(); 
} 
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************
void deleteIndividualRecord(Account customer) 
{ 
	long record; 
	//Open file 
	fstream citizen("Customer.txt", ios::in | ios::binary); 
 
	if(!citizen) 
	{ 
		cout << "Error opening file.\n"; 
		exit(0); 
	} 

	cout << "What record would you like to delete?	"; 
	cin  >> record; 
	cout << endl; 
 
	//delete citizen.seekg(record * sizeof(customer), ios::beg); 
 
	cout << "Deleted record " << record << "." << endl; 
	 
	citizen.close(); 
 
 
	/*char search[NAME]; 
	char *strPtr = NULL; 
 
	cout << "Enter a Name to searh for: (Capital letter first) "; 
	cin.getline(search, NAME); 
 
	int i = 0; 
	while(i < 3) 
	{ 
		strPtr = strstr([i].name, search); 
		if (strPtr != NULL) 
		{ 
			cout << info[i].name << endl; 
		} 
		i++; 
	} 
 
	char response; 
	//Create file object and open file to display customer information 
	fstream citizen("Customers.txt", ios::in | ios::binary); 
 
	//Test for file open error 
	if(!citizen) 
	{ 
		cout << "Error opening file. Shutting down.\n"; 
		exit(0); 
	} 
	else 
	{ 
		cout << "Wachovia Customers:\n\n"; 
 
		//Read one structure at a time and echo to screen. 
		citizen.read(reinterpret_cast<char *>(&customer), 
					 sizeof(customer)); 
		while(!citizen.eof()) 
		{ 
			cout << "Name:	" << customer.name << endl; 
 
			cout << "Address:	" << customer.address << endl; 
 
			cout << "City, State, and Zip:	" << customer.cityStateZip << endl; 
 
			cout << "Telephone Number:	" << customer.teleNumber << endl; 
 
			cout << fixed << showpoint << setprecision(2); 
			cout << "Account Balance:	" << "$" << customer.accountBalance << endl; 
 
			cout << "Date of Last Payment(mm/dd/yyyy):	" << customer.lastPayment << endl; 
			cout << "\nStrike any key to see the next record.\n"; 
			cin.get(response); 
			citizen.read(reinterpret_cast<char *>(&customer), 
						 sizeof(customer)); 
		} 
		cout << "That is all the information in the file.\n"; 
	} 
	
} */
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************/ 
void changeIndividualRecord(Account &customer) 
{ 
	long record; 
	char response;
 
	//Open file 
	fstream citizen("DataBase.txt", ios::in | ios::out | ios::binary); 
 
	if(!citizen) 
	{ 
		cout << "Error opening file.\n"; 
		exit(0); 
	} 
 
	cout << "\nWhat record would you like to change?	"; 
	cin  >> record; 
 
	citizen.seekg(record * sizeof(customer), ios::beg); 
	citizen.read(reinterpret_cast<char *>(&customer), sizeof(customer)); 
 
	//Old information 
	cout << "\n\nName:					  " << customer.name << endl; 
	cout << "Address:				   " << customer.address << endl; 
	cout << "City, State, and Zip:	  " << customer.cityStateZip << endl; 
	cout << "Telephone Number:		  " << customer.teleNumber << endl; 
	cout << fixed << showpoint << setprecision(2); 
	cout << "Account Balance:		  " << "$" << customer.accountBalance << endl; 
	cout << "Last Payment(mm/dd/yyyy):  " << customer.lastPayment << endl; 
 
 
	cout << "\nEnter new information for customer:\n"; 

	cout << "Do you want to update the customer's name(Y/N)?	";
	cin  >> response;
	if(toupper(response) == 'Y')
	{
		cout << "Name:					   ";		 
		cin.get(); 
		cin.getline(customer.name, NAME); 
	}
	else
		cout << "Customer's name has not been updated.";

	cout << "\n\nDo you want to update the customer's address(Y/N)?	";
	cin  >> response;
	if(toupper(response) == 'Y')
	{
		cout << "Address:					"; 
		cin.get(); 
		cin.getline(customer.address, ADDRESS);
	}
	else
		cout << "Customer's address has not be updated.";
	
	cout << "\n\nDo you want to update the City, State, and Zip code(Y/N)?	";
	cin  >> response;
	if(toupper(response) == 'Y')
	{	
		cout << "City, State, and Zip:	   "; 
		cin.get(); 
		cin.getline(customer.cityStateZip, HOMETOWN);
	}
	else
		cout << "City, State, and Zip code has not be updated for this customer.";

	cout << "\n\nDo you want to update the customer's telephone number(Y/N)?	";
	cin  >> response;
	if(toupper(response) == 'Y')
	{	
		cout << "Telephone Number:		   "; 
		cin.get(); 
		cin.getline(customer.teleNumber, TELEPHONE); 
	}
	else
		cout << "Customer's telephone number has not been updated.";

	cout << "\n\nDo you want to update the customer's account balance(Y/N)?	";
	cin  >> response;
	if(toupper(response) == 'Y')
	{
		cout << "Account Balance:			"; 
		cin.get(); 
		cin  >> customer.accountBalance; 
		while(customer.accountBalance < 0.00) 
		{ 
			cout << "Invalid! Customer's account balance must be greater\n" 
				 << "than or equal to $0.00. Please re-enter in customer's\n" 
				 << "account balance:\n"; 
			cin  >> customer.accountBalance; 
		} 
	}
	else
		cout << "Customer's account balance has not been updated.";

	cout << "\n\nDo you want to update date of last payment the customer made(Y/N)?	";
	cin  >> response;
	if(toupper(response) == 'Y')
	{
		cout << "Last Payement(mm/dd/yyyy):  "; 
		cin.get(); 
		cin.getline(customer.lastPayment, LAST_PAYMENT);
	}
	else
		cout << "Date of last payment has not been updated.\n\n";
 
	citizen.seekp(record * sizeof(customer), ios::beg); 
	citizen.write(reinterpret_cast<char *>(&customer), sizeof(customer)); 
 
	//Close file 
	citizen.close(); 
} 
 
 
/*************************************************** 
 * 
 * 
 * 
 * 
 ***************************************************/ 
void displayFile(Account customer) 
{ 
	//Create file object and open file to display customer information 
	fstream citizen("DataBase.txt", ios::in | ios::binary); 
 
	//Test for file open error 
	if(!citizen) 
	{ 
		cout << "Error opening file. Shutting down.\n"; 
		exit(0); 
	} 
	else 
	{ 
		cout << "\n\tWachovia Customers:\n"; 
 
		//Read one structure at a time and echo to screen. 
		citizen.read(reinterpret_cast<char *>(&customer), 
					 sizeof(customer)); 
		while(!citizen.eof()) 
		{ 
			cout << "\nName:					  " << customer.name << endl; 
			cout << "Address:				   " << customer.address << endl; 
			cout << "City, State, and Zip:	  " << customer.cityStateZip << endl; 
			cout << "Telephone Number:		  " << customer.teleNumber << endl; 
			cout << fixed << showpoint << setprecision(2); 
			cout << "Account Balance:		  " << "$" << customer.accountBalance << endl; 
			cout << "Last Payment(mm/dd/yyyy):  " << customer.lastPayment << endl; 
			citizen.read(reinterpret_cast<char *>(&customer), 
						 sizeof(customer)); 
		} 
		cout << "\nThat is all the information in the file.\n"; 
	} 
	citizen.close(); 
}



Is This A Good Question/Topic? 0
  • +

Replies To: Avanced File I/O

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 3873
  • View blog
  • Posts: 11,412
  • Joined: 18-April 07

Re: Avanced File I/O

Posted 07 November 2008 - 10:29 PM

Well your problem is not a programming problem, it is a design choice really. This is the classic choice most designers face when it comes to accessing records... which is the most efficient way of getting at a record within a list of records? You could go with a sequential search where you load each record into the structure and then compare the name with the name of the record until you find it... or better yet you can do what databases do, index it!

When you go to write each account to the file, also store the record number and name of the client into an array. Use this array for your search. When someone enters the name, search the array of names, find it, grab the index key associated with that name, then you know which record number to find in the file. This will prevent you from having to read through all the records, you can quickly jump to that place in the file with your seekg method.

With this array of names and their corresponding record numbers, you can perform the many variants of search and rather quick too.

This array will be your index to the file which will map a name to the record number of the file. When you add or remove from the file, you also add and remove from the array.

So you have those two main choices... sequential search through using the structure or build yourself an indexing array. :)
Was This Post Helpful? 1

#3 SCStudent86  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 06-October 08

Re: Avanced File I/O

Posted 08 November 2008 - 10:36 AM

View PostMartyr2, on 7 Nov, 2008 - 09:29 PM, said:

Well your problem is not a programming problem, it is a design choice really. This is the classic choice most designers face when it comes to accessing records... which is the most efficient way of getting at a record within a list of records? You could go with a sequential search where you load each record into the structure and then compare the name with the name of the record until you find it... or better yet you can do what databases do, index it!

When you go to write each account to the file, also store the record number and name of the client into an array. Use this array for your search. When someone enters the name, search the array of names, find it, grab the index key associated with that name, then you know which record number to find in the file. This will prevent you from having to read through all the records, you can quickly jump to that place in the file with your seekg method.

With this array of names and their corresponding record numbers, you can perform the many variants of search and rather quick too.

This array will be your index to the file which will map a name to the record number of the file. When you add or remove from the file, you also add and remove from the array.

So you have those two main choices... sequential search through using the structure or build yourself an indexing array. :)

If I use an indexing array, can I still read/write the information in binary format? Oh and another question. Since I'm creating an array that will hold the person's name and the record number as the index, say [2], how is the array going to be initialized in the beginning when there is no records in the database? Just set the array to size 0 and when I enter in a new record change it??
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1