PC Pals Forum
Technical Help & Discussion => Website Design & Programming => Topic started by: davypipes on November 20, 2004, 09:26
-
hi guys!!!
ive been making this program thats supposed to store a number of records to a binary file.the problem ive encountered is with placing a record in a temporary object so that i can later on work on that data.i defined a class for this purpose as follows:
class temp
{
public:
char farmerName[20];
long idNumber;
long accountNumber;
char location[30];
};
and passed on the info from the file as follows:
// function to edit the farmer details...
void Farmer::editFarmer()
{
fstream myfile("Farmer.dat",ios::in | ios::out | ios::binary) ;
temp temprec;
clrscr();
cout<<"\t\tYOU HAVE CHOSEN TO EDIT A RECORD \n";
cout<<"\t\t------------------------------------\n\n";
while(myfile>>farmerName>>idNumber>>accountNumber>>location)
{
temprec.farmerName=farmerName;
//error raised on previous line:Lvalue required
temprec.idNumber=idNumber;
temprec.accountNumber=accountNumber;
temprec.location=location;
//error raised on previous line:Lvalue required
}
}
the error ive been gettting is been raissed when i pass the farmername and the location variables which are both of type char.the rest seems to be working fine ...its just those 2 lines!!!
so ....anyone?? :-\
-
Sorry, I havent a clue about that stuff, hopefully someone will be along soon who may be able to help you out ???
-
Another job for Dack, me thinks. ;)
-
http://www.parashift.com/c++-faq-lite/serialization.html#faq-35.6 (http://www.parashift.com/c++-faq-lite/serialization.html#faq-35.6)
In other words, storing character data is not really recommended that way as you are never exactly sure where it's going to end.
Better to use the Read() and Write() functions for the character and location fields.
Assuming the farmerName and location variables are defined as per the structure i.e. char [ 20 ].
Remember that (in most instances) temprec.farmerName is actually an address - equivalent to &temprec.farmerName[ 0 ]. If you use that in your code you should see the error :)
i.e. you are trying to say:
&temprec.farmerName[ 0 ]= &farmerName[ 0 ]
You could use a memcpy(temprec.farmerName, farmerName, sizeof(temprec.farmerName)); to get rid of the error.
-
hmmmm.....
so i gueess lem me try out the write() and read() functions!! hopefully all will go well and thanks for the advice!! ;)
-
ok!!! thats it....i really need someone with a good idea on how am to edit the farmer records!!!!rather ...how am supposed to edit a farmer's details,eg name...location..acc number!!!
heres what ive been able to do so far!!!!
#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();
};
void waitmsg()
{
cout<<"PRESS RETURN [enter]TO EXIT";
getchar();
}
//procedure for printing a record
void Farmer::viewFarmer()
{
int i=1;
ifstream myfile("Farmers.dat",ios::in) ;
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>>farmerName>>idNumber>>accountNumber>>location)
{
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()
{
ofstream myfile("Farmers.dat",ios::app);
clrscr();
char choice ='y';
while (choice=='y' || choice=='Y')
{
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;
//save the entered data to file*/
myfile<<farmerName<<" "<<idNumber<<" "<<accountNumber<<" "<<location<<" \n" ;
cout <<"Dou you want to enter another record Y(es) N(o) ?";
cin >> choice;
}
myfile.close();
}
//function to edit the record..
//heres tthe problem area....
/*void editfarmer()
{
} */
/*procedure for searching a record */
void Farmer::searchFarmer()
{
ifstream myfile("a:Farmers.dat",ios::in);
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;
while((myfile>>farmerName>>idNumber>>accountNumber>>location) && (accountNumber != searchkey))
{ }
if(accountNumber == 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;
myfile.close();
waitmsg();
}
//Definition of function mainMenu
//Displays the main menu and asks the user to select
void Farmer::mainMenu(void)
{
int Choice;
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|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|\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 > 4);
switch (Choice)
{
case 1 :registerFarmer();mainMenu() ;break;
case 2 :viewFarmer();mainMenu() ;break;
case 3 :searchFarmer();mainMenu() ;break;
// case 4:editfarmer()mainmenu();break;
}
}
void main()
{
Farmer fDetails;
fDetails.mainMenu();
}
-
Hopefully Dack will be along soon to help you with that! :o
-
*LOTS* to do here I'm afraid :( First question is what C++ compiler are you using - clrscr isn't a standard MS function you see but is in Borland C.
Lets start with the easy ones:
1. Your menu function is recursive which would lead to memory errors. There is also no way of exiting the program safely.
Your code:
void Farmer::mainMenu(void)
{
int Choice;
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|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|\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 > 4);
switch (Choice)
{
case 1 :registerFarmer();mainMenu() ;break;
case 2 :viewFarmer();mainMenu() ;break;
case 3 :searchFarmer();mainMenu() ;break;
// case 4:editfarmer()mainmenu();break;
}
}
This works better if written as:
void Farmer::mainMenu(void)
{
int Choice = 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()mainmenu();break;
default: break;
}
}while (Choice != 5);
}
-
2. Your registerfarmer routine doesn't check to see if the number already exists in the file - if so you should say that there is a duplicate entry.
void Farmer::registerFarmer()
{
ofstream myfile("Farmers.dat",ios::app);
clrscr();
char choice ='y';
while (choice=='y' || choice=='Y')
{
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;
//save the entered data to file*/
myfile<<farmerName<<" "<<idNumber<<" "<<accountNumber<<" "<<location<<" \n" ;
cout <<"Dou you want to enter another record Y(es) N(o) ?";
cin >> choice;
}
myfile.close();
}
Should be:
void Farmer::registerFarmer()
{
clrscr();
char choice ='y';
while (choice=='y' || choice=='Y')
{
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("Farmers.dat",ios::app);
myfile<<farmerName<<" "<<idNumber<<" "<<accountNumber<<" "<<location<<" \n" ;
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;
}
}
/*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("C:Farmers.dat",ios::in);
while((myfile>>LocalFarmerName>>nLocalIDNumber>>nLocalAccountNumber>>LocalLocation)
&& (nLocalAccountNumber != nSearchKey))
{ };
// 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;
strncpy(farmerName, LocalFarmerName, 20);
strncpy(location, LocalLocation, 30);
bRetVal = true;
}
// Close the file
myfile.close();
return bRetVal;
}
The searchforexisting function will be useful in a minute :)
-
If you put those routines in then you'll see the problem I was on about concerning using write and read for the stream processing. If you open the farmers.dat file you'll see that each record you entered was a different size (because of the length of the text fields). You should now realise that you have to make all records the same (maximum size) in case you have to edit one and the new data will take up more space in the file than the existing data.
This involves simply changing the file input and output routines to use the read/write commands. We will then know how big each record is (20 bytes + the size of a long + the size of a long plus 30 bytes)
The edit routine then comes down to:
1. Get search key
2. find record that key matches
3. update fields in memory
4. open file for reading and writing
5. find place in file to change
6. write data
7. close file.
To make a read/write file you need to use the fstream type and the tellg and seekp operators.
-
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 :)
// 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();
}
-
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 :)
// 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();
}
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!! :-\...
-
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!! :-\...
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.
-
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?
-
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).
-
thanks again!!! and oohhhh....HAPPY NEW YEAR!!! so i kinda wanted to ask you some advice...well on programming languaghes!! since i see uve done alot..some of them ive never had off :-\(z80..isnt that some kind of robot? ;D) Is delphi better than vb?
a friend of mine was telling me that u can make an appl with delphi which will be smaller than the same one done on vb!!! is this true :-\
-
Size isn't always that important :)
You can get better speed results using a massive, pre-computed look up table in some application than a much smaller bit of code that computes the values dynamically. It's very much a 'horses for courses' kind of argument.
My view?
Visual basic easy to learn and develop applications quickly - latest .NET version much better than older versions. However you are limited to Microsoft's language - though it does propagate to other MS products e.g. Excel.
Delphi is probably best thought of as a visual version of Pascal - free download from http://www.borland.com/products/downloads/download_delphi.html (http://www.borland.com/products/downloads/download_delphi.html). Better for 'real' work and tends to be faster. You might want to have a search for DeDe too ;) Also look at Kylix.
C/C++ - current language of choice as I've developed lots of useful classes over the years which make development easier for me. Can be incredible infuruating though - Microsoft development environment not too bad. Because of the wealth of people programming in it there are usually routines available to perform any task you need (though most require a bit of tweaking).
Good place to look at for examples is over at www.codeguru.com (http://www.codeguru.com)