Technical Help & Discussion > Website Design & Programming
c++ binary file ops
Dack:
Full code to do what you are after is something like this.
You will need to properly modify the editing function (I just put the one field in).
Should be a good start for you though :)
--- Quote ---// farmer.cpp : Defines the entry point for the console application.
//
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include <conio.h>
#include <iomanip.h>
#include <stdio.h>
/*
*************************************************************
program description
*************************************************************
this is a program for storing farmers records
the functions include:
registering farmers
searching for a specific farmer
viewing farmer records!
*************************************************************
*/
class Farmer
{
char farmerName[20];
long idNumber;
long accountNumber;
char location[30];
public:
void mainMenu();
void registerFarmer();
void searchFarmer();
void viewFarmer();
void editfarmer();
bool SearchForExisting(long nSearchKey);
};
void waitmsg()
{
cout<<"PRESS RETURN [enter]TO EXIT";
getchar();
}
//procedure for printing a record
void Farmer::viewFarmer()
{
int i=1;
ifstream myfile("a:Farmers.dat",ios::in|ios::binary) ;
clrscr();
cout<<" LIST OF ALL REGISTERED FARMERS \n\n"<<endl;
cout<<" "<<setw(5)<<"FARMER NAME"<<setw(17)<<"ID NUMBER"<<setw(17)<<"ACCOUNT NUMBER"<<setw(17)<<"LOCATION"<<setw(17)<<endl;
cout<<"-----------------------------------------------------------------------------"<<endl<<endl;
while(!myfile.fail())
{
myfile.read(farmerName, sizeof(farmerName));
myfile.read((char *)&idNumber, sizeof(idNumber));
myfile.read((char *)&accountNumber, sizeof(accountNumber));
myfile.read(location, sizeof(location));
// now need to check there has not been an error in reading as the eof flag is not
// set until a file read has been done - this means an empty file still runs through
// here once
if (!myfile.fail())
{
cout <<i<<" "<<setw(7)<<farmerName<<setw(18)<<idNumber<<setw(17)<<accountNumber<<setw(17)<<location<<setw(17)<<endl<<endl;
i++;
}
}
cout<<"\n-------------------------END OF RECORDS----------------------------"<<endl;
myfile.close();
waitmsg();
}
void Farmer::registerFarmer()
{
clrscr();
char choice ='y';
while (choice=='y' || choice=='Y')
{
// clear out the variables
memset(farmerName, sizeof(farmerName), 0);
memset(location, sizeof(location),0);
idNumber = 0;
accountNumber = 0;
clrscr();
cout<<"\t\tYOU HAVE CHOSEN TO REGISTER A NEW FARMER \n";
cout<<"\t\t----------------------------------------\n\n";
cout <<"Please type in the details for the farmer \n\n";
cout <<"Farmer Name :"; cin >>farmerName;
cout <<"\nFarmer ID Number :"; cin >>idNumber;
cout <<"\nFarmer Account Number :"; cin >>accountNumber;
cout <<"\nPhysical Location :"; cin >>location;
// See if he already exists
if (false==SearchForExisting(accountNumber))
{
//save the entered data to file
ofstream myfile("a:Farmers.dat",ios::app|ios::binary);
myfile.write(farmerName, sizeof(farmerName));
myfile.write((char *)&idNumber, sizeof(idNumber));
myfile.write((char *)&accountNumber, sizeof(accountNumber));
myfile.write(location, sizeof(location));
myfile.close();
}
else
{
cout << "\nFarmer already exists";
cout << "\n" << farmerName<<" "<<idNumber<<" "<<accountNumber<<" "<<location<<" \n" ;
}
cout <<"Do you want to enter another record Y(es) N(o) ?";
cin >> choice;
}
}
//function to edit the record..
//heres tthe problem area....
void Farmer::editfarmer()
{
char cChoice = 'y';
long nSearchKey = 0;
long nLocalAccountNumber = -1;
long nLocalIDNumber = -1;
char LocalFarmerName[20];
char LocalLocation[30];
long nPosition;
// get the searchID
cout << "Enter search key ";
cin >> nSearchKey;
// see if it already exists - due to the way the search is written
// our variables contain the values we want to change
if (true==SearchForExisting(nSearchKey))
{
// display existing record values
cout << "\n" << farmerName<<" "<<idNumber<<" "<<accountNumber<<" "<<location<<" \n" ;
// allow them to be altered
cout << "\nEnter new farmername";
cin >> farmerName;
// etc.. for all the fields
// Do you really want to save?
do{
cout << "\nUpdate record (Y/N)";
cin >> cChoice;
cChoice = toupper(cChoice);
} while (('Y'!=cChoice)
&&('N'!=cChoice));
// If yes:
if ('Y'==cChoice)
{
// open file for input and output
fstream myfile("a:Farmers.dat",ios::in|ios::out|ios::binary);
// read file until matching record
while ( (!myfile.fail())&&
(nSearchKey!=nLocalIDNumber))
{
// read into local variables
myfile.read(LocalFarmerName, sizeof(LocalFarmerName));
myfile.read((char *)&nLocalIDNumber, sizeof(nLocalIDNumber));
myfile.read((char *)&nLocalAccountNumber, sizeof(nLocalAccountNumber));
myfile.read(LocalLocation, sizeof(LocalLocation));
}
// we are now one record past the data we want to change so change the file pointer
// back by the size of the record
nPosition = myfile.tellg();
// move back by record size
nPosition -= sizeof(farmerName);
nPosition -= sizeof(idNumber);
nPosition -= sizeof(accountNumber);
nPosition -= sizeof(location);
// now set the pointer for where we are going to write
// from the beginning of the file
myfile.seekp(nPosition,ios::beg);
// output the values of the data - overwriting existing record
myfile.write(farmerName, sizeof(farmerName));
myfile.write((char *)&idNumber, sizeof(idNumber));
myfile.write((char *)&accountNumber, sizeof(accountNumber));
myfile.write(location, sizeof(location));
// now close the file
myfile.close();
cout << "\nEntry changed";
}
else
{
// If No: throw away the data -
cout << "\n Discarding changes";
}
}
else
{
// Record not found
cout << "\nentry not found for that search key";
}
waitmsg();
}
/*procedure for searching a record */
void Farmer::searchFarmer()
{
long int searchkey;
clrscr();
cout<<"\t\tYOU HAVE CHOSEN TO SEARCH FOR A FARMER \n";
cout<<"\t\t----------------------------------------\n\n";
cout<<"Please enter the account number of the farmer : ";
cin>> searchkey;
if (true==SearchForExisting(searchkey))
{
cout <<"\n Farmer Name : "<<farmerName<<"\nFarmer ID Number : "<<idNumber<<"\nFarmer Account Number : "<<accountNumber<<"\nFarmer Location : "<<location<<endl<<endl;
}
else
cout<<"\n \t \t Record not found !\n\n\n\n\n" ;
cout<<"\n-------------------------END OF RECORDS----------------------------"<<endl;
waitmsg();
}
// New function that searches for an existing record and reads the values
// into the buffer if we already have them
bool Farmer::SearchForExisting(long nSearchKey)
{
// Initially show that we have not found the searchfield
bool bRetVal = false;
long nLocalAccountNumber = -1;
long nLocalIDNumber = -1;
char LocalFarmerName[20];
char LocalLocation[30];
// Open the file for reading
ifstream myfile("a:Farmers.dat",ios::in|ios::binary);
while((!myfile.fail())&&
(nLocalAccountNumber!=nSearchKey))
{
myfile.read(LocalFarmerName, sizeof(LocalFarmerName));
myfile.read((char *)&nLocalIDNumber, sizeof(nLocalIDNumber));
myfile.read((char *)&nLocalAccountNumber, sizeof(nLocalAccountNumber));
myfile.read(LocalLocation, sizeof(LocalLocation));
};
// indicate in the return that we have found the value
// and update the values in out local record
if(nLocalAccountNumber == nSearchKey)
{
idNumber = nLocalIDNumber;
accountNumber = nLocalAccountNumber;
memcpy(farmerName, LocalFarmerName, 20);
memcpy(location, LocalLocation, 30);
bRetVal = true;
}
// Close the file
myfile.close();
return bRetVal;
}
//Definition of function mainMenu
//Displays the main menu and asks the user to select
void Farmer::mainMenu(void)
{
int Choice = 0;
// clear out all the variable space
memset(farmerName, sizeof(farmerName), 0);
memset(location, sizeof(location), 0);
do
{
do
{
clrscr();
cout<<"\n\n\tWELCOME TO THE WATAMU DAIRY FARMERS COOPERATIVE SOCIETY\n\n\n\n";
cout<<"\t\t|- - - - - - - - - - - - - - - -|\n" ;
cout<<"\t\t|\tTAMU DAIRY FARMERS\t|\n";
cout<<"\t\t|-------------------------------|\n";
cout<<"\t\t|\t FARMERS RECORDS\t|\n";
cout<<"\t\t|\t1.Register New Farmer\t|\n";
cout<<"\t\t|\t2.View Farmer Records\t|\n";
cout<<"\t\t|\t3.Search Farmer Record\t|\n";
cout<<"\t\t|\t4.edit Farmer record\t|\n";
cout<<"\t\t|\t5.Exit program\t\t|\n";
cout<<"\t\t|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|\n\n " ;
cout<<"\tEnter 1 , 2 , 3 , 4 , 5 or 6 : ";
cin>>Choice;
}
//when the choice is not among the options
while (Choice < 1 || Choice > 5);
switch (Choice)
{
case 1 :registerFarmer();break;
case 2 :viewFarmer();break;
case 3 :searchFarmer();break;
case 4:editfarmer();break;
default: break;
}
}while (Choice != 5);
}
void main()
{
Farmer fDetails;
fDetails.mainMenu();
}
--- End quote ---
davypipes:
--- Quote from: Dack on November 30, 2004, 01:18 ---
Full code to do what you are after is something like this.
You will need to properly modify the editing function (I just put the one field in).
Should be a good start for you though :)
--- Quote ---// farmer.cpp : Defines the entry point for the console application.
//
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include <conio.h>
#include <iomanip.h>
#include <stdio.h>
/*
*************************************************************
program description
*************************************************************
this is a program for storing farmers records
the functions include:
registering farmers
searching for a specific farmer
viewing farmer records!
*************************************************************
*/
class Farmer
{
char farmerName[20];
long idNumber;
long accountNumber;
char location[30];
public:
void mainMenu();
void registerFarmer();
void searchFarmer();
void viewFarmer();
void editfarmer();
bool SearchForExisting(long nSearchKey);
};
void waitmsg()
{
cout<<"PRESS RETURN [enter]TO EXIT";
getchar();
}
//procedure for printing a record
void Farmer::viewFarmer()
{
....
....
...
}
void Farmer::registerFarmer()
{
....
....
...
clrscr();
char choice ='y'; }
}
//function to edit the record..
//heres tthe problem area....
void Farmer::editfarmer()
{
char cChoice = 'y';
long nSearchKey = 0;
long nLocalAccountNumber = -1;
long nLocalIDNumber = -1;
char LocalFarmerName[20];
char LocalLocation[30];
long nPosition;
// get the searchID
cout << "Enter search key ";
cin >> nSearchKey;
// see if it already exists - due to the way the search is written
// our variables contain the values we want to change
if (true==SearchForExisting(nSearchKey))
{
// display existing record values
cout << "\n" << farmerName<<" "<<idNumber<<" "<<accountNumber<<" "<<location<<" \n" ;
// allow them to be altered
cout << "\nEnter new farmername";
cin >> farmerName;
// etc.. for all the fields
// Do you really want to save?
do{
cout << "\nUpdate record (Y/N)";
cin >> cChoice;
cChoice = toupper(cChoice);
} while (('Y'!=cChoice)
&&('N'!=cChoice));
// If yes:
if ('Y'==cChoice)
{
// open file for input and output
fstream myfile("a:Farmers.dat",ios::in|ios::out|ios::binary);
// read file until matching record
while ( (!myfile.fail())&&
(nSearchKey!=nLocalIDNumber))
{
// read into local variables
myfile.read(LocalFarmerName, sizeof(LocalFarmerName));
myfile.read((char *)&nLocalIDNumber, sizeof(nLocalIDNumber));
myfile.read((char *)&nLocalAccountNumber, sizeof(nLocalAccountNumber));
myfile.read(LocalLocation, sizeof(LocalLocation));
}
// we are now one record past the data we want to change so change the file pointer
// back by the size of the record
nPosition = myfile.tellg();
// move back by record size
nPosition -= sizeof(farmerName);
nPosition -= sizeof(idNumber);
nPosition -= sizeof(accountNumber);
nPosition -= sizeof(location);
// now set the pointer for where we are going to write
// from the beginning of the file
myfile.seekp(nPosition,ios::beg);
// output the values of the data - overwriting existing record
myfile.write(farmerName, sizeof(farmerName));
myfile.write((char *)&idNumber, sizeof(idNumber));
myfile.write((char *)&accountNumber, sizeof(accountNumber));
myfile.write(location, sizeof(location));
// now close the file
myfile.close();
cout << "\nEntry changed";
}
else
{
// If No: throw away the data -
cout << "\n Discarding changes";
}
}
else
{
// Record not found
cout << "\nentry not found for that search key";
}
waitmsg();
}
/*procedure for searching a record */
void Farmer::searchFarmer()
{
long int searchkey;
clrscr();
cout<<"\t\tYOU HAVE CHOSEN TO SEARCH FOR A FARMER \n";
cout<<"\t\t----------------------------------------\n\n";
cout<<"Please enter the account number of the farmer : ";
cin>> searchkey;
if (true==SearchForExisting(searchkey))
{
cout <<"\n Farmer Name : "<<farmerName<<"\nFarmer ID Number : "<<idNumber<<"\nFarmer Account Number : "<<accountNumber<<"\nFarmer Location : "<<location<<endl<<endl;
}
else
cout<<"\n \t \t Record not found !\n\n\n\n\n" ;
cout<<"\n-------------------------END OF RECORDS----------------------------"<<endl;
waitmsg();
}
// New function that searches for an existing record and reads the values
// into the buffer if we already have them
bool Farmer::SearchForExisting(long nSearchKey)
{
// Initially show that we have not found the searchfield
bool bRetVal = false;
long nLocalAccountNumber = -1;
long nLocalIDNumber = -1;
char LocalFarmerName[20];
char LocalLocation[30];
// Open the file for reading
ifstream myfile("a:Farmers.dat",ios::in|ios::binary);
while((!myfile.fail())&&
(nLocalAccountNumber!=nSearchKey))
{
myfile.read(LocalFarmerName, sizeof(LocalFarmerName));
myfile.read((char *)&nLocalIDNumber, sizeof(nLocalIDNumber));
myfile.read((char *)&nLocalAccountNumber, sizeof(nLocalAccountNumber));
myfile.read(LocalLocation, sizeof(LocalLocation));
};
// indicate in the return that we have found the value
// and update the values in out local record
if(nLocalAccountNumber == nSearchKey)
{
idNumber = nLocalIDNumber;
accountNumber = nLocalAccountNumber;
memcpy(farmerName, LocalFarmerName, 20);
memcpy(location, LocalLocation, 30);
bRetVal = true;
}
// Close the file
myfile.close();
return bRetVal;
}
//Definition of function mainMenu
//Displays the main menu and asks the user to select
void Farmer::mainMenu(void)
{
int Choice = 0;
// clear out all the variable space
memset(farmerName, sizeof(farmerName), 0);
memset(location, sizeof(location), 0);
do
{
do
{
clrscr();
cout<<"\n\n\tWELCOME TO THE WATAMU DAIRY FARMERS COOPERATIVE SOCIETY\n\n\n\n";
cout<<"\t\t|- - - - - - - - - - - - - - - -|\n" ;
cout<<"\t\t|\tTAMU DAIRY FARMERS\t|\n";
cout<<"\t\t|-------------------------------|\n";
cout<<"\t\t|\t FARMERS RECORDS\t|\n";
cout<<"\t\t|\t1.Register New Farmer\t|\n";
cout<<"\t\t|\t2.View Farmer Records\t|\n";
cout<<"\t\t|\t3.Search Farmer Record\t|\n";
cout<<"\t\t|\t4.edit Farmer record\t|\n";
cout<<"\t\t|\t5.Exit program\t\t|\n";
cout<<"\t\t|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|\n\n " ;
cout<<"\tEnter 1 , 2 , 3 , 4 , 5 or 6 : ";
cin>>Choice;
}
//when the choice is not among the options
while (Choice < 1 || Choice > 5);
switch (Choice)
{
case 1 :registerFarmer();break;
case 2 :viewFarmer();break;
case 3 :searchFarmer();break;
case 4:editfarmer();break;
default: break;
}
}while (Choice != 5);
}
void main()
{
Farmer fDetails;
fDetails.mainMenu();
}
--- End quote ---
--- End quote ---
hi thanks again for the insight..especially for the edit farmer function and the menu function on memory wastage...personally i hadnt thought about that...that recursion would bring me problems...anyway ...emmmm wat did i wanna say?....ooooh...yeah...ahh about the edit function..shouldnt i open the file first before displaying the record if found???or when the condition is been checked on this statement " if (true==SearchForExisting(nSearchKey))", the file is already opened by the "searchforexisting()" function? and anyway within the function the file is closed?or does this have to do with the file buffers ur talking about ie: the data is still available in memeory even after closing a file?
am using the borland c++ compiler..which funny enuff doesnt identify the bool type!! :-\...
Dack:
--- Quote from: davypipes on November 30, 2004, 09:59 ---
hi thanks again for the insight..especially for the edit farmer function and the menu function on memory wastage...personally i hadnt thought about that...that recursion would bring me problems...anyway ...emmmm wat did i wanna say?....ooooh...yeah...ahh about the edit function..shouldnt i open the file first before displaying the record if found???or when the condition is been checked on this statement " if (true==SearchForExisting(nSearchKey))", the file is already opened by the "searchforexisting()" function? and anyway within the function the file is closed?or does this have to do with the file buffers ur talking about ie: the data is still available in memeory even after closing a file?
am using the borland c++ compiler..which funny enuff doesnt identify the bool type!! :-\...
--- End quote ---
BOOL is just an integer with 0 as FALSE and any non zero value as TRUE (Should be !0 = 0xFFFFFFFF really). You can use these yourself by doing the equivalent #defines at the top of the code. i.e.
#define bool int
#define true 0xFFFFFFFF
#define false 0
The search routine just:
1. opens file
2. reads a block of data in
3. checks to see if the end of file has been reached or the block is the one we are looking for
4. If block found the we already have the rest of the parameters in memory so we might as well just store them.
5. returns a value to say whether we found the data
I think one of the problems you have got with the skeleton code is that it is too specifically tied to one use - sort of going against the idea of code reusability that should be a feature of C++. You are only really using the class as an envelope. You could simply have renamed the menu function as main.
What I would have done is:
1. Define a class for the Farmer RECORD - functions to use include the standard Set/Get and overload of the << and >> operations.
2. Define a class that linked a passed filename to multiple farmer records and that supported record ADD, DELETE, VIEW and EDIT. This will be using instances of Class 1.
3. In a main application create an instance of the file class, open the file you want to use, and use the main application to perform the functions on Class 2. e.g get a record and add to file, edit existing record, display records etc.
Hiatus:
Wow....and to think that I'll be learning all this in the next few months...if that doesn't look like fun, i don't know what does! ;D
Btw...just out of curiosity, how many programming languages do u know Dack?
Dack:
Lets try and think back :)
High level recent ones:
C++, C, (Borland and Microsoft IDEs), Pascal, Visual Basic, Coral 66, JAVA
Low level (recent):
68000, 80x86, Microchip Pic, FR30, Mips, 6502, ADSP210x
Old languages (I used to use -or played with):
CESIL, True BASIC, USCD Pascal, Prolog, Pilot, Z80, Cobol
Couple of other odd uControllers too (from when I was writing DVD player code).
But it's possible to write Basic in any language :)
I tend to be involved in quite low level stuff (current stuff is device driver level under Windows NT for some legacy kit).
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version