delete record

Pages: 12
isn't u mean that i can declare any size for my const RecordSize?
RecordSize is exactly what the name says: Imagine if you want that the elements should consists of
EmployeeID 10 char
EmployeeFirstName 30 char
EmployeeLastName 30 char
EmployeeDepartment 30 char
EmployeePosition 30 char
EmployeeWorkHours 10 char
PayRate 10 char
totalSalary 10 char
if I calculated it right the amount of char/bytes to hold the data, i.e. const int RecordSize = 160;
As a struct it would look like this:
1
2
3
4
5
6
7
8
9
10
11
12
struct Data
{
  char EmployeeID[10]
  char EmployeeFirstName[30]
  char EmployeeLastName[30]
  char EmployeeDepartment[30]
  char EmployeePosition[30]
  char EmployeeWorkHours[10]
  char PayRate[10]
  char totalSalary[10]
}; // if the struct exist this way (only POD http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html / not string) you can write:
const int RecordSize = sizeof(Data);



You may consider a file as an [infinite] series of char.
Your task is it to read and write from this char array. Somewhat like:
1
2
3
4
5
6
7
8
int main(){
	char file[1000000];
	Employee theEmployee;
	int index = 0;
	char choice;
	char choice2;

	readRecord( file, &theEmployee , index );
By the way: for random acces you should open the file at the beginning and close it at the end instead of opening/closing it all the time

but when me pass value to the index

the value holding is 0 .
Yes, the index 0 is the index of the first record. It's not the size! You can read the size once at the beginning and write it whenever you add a record
@coder777

i think i already follow what i have to do?
in my main i declare as yours
1
2
3
4
5
6
7
8
9
10
int main(){
	
	char file[1000000];
	Employee theEmployee[30];
	Employee theEmployee1;
	int size = 0;
	char choice;
	char choice2;

	readRecord( file , &theEmployee1 , size );


in my implementation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const int RecordSize = sizeof(Employee);

void readRecord(char file[] ,Employee *theEmployee , int index){ // Note that you have an index instead of size

	ifstream inFile;
	string filename;

	cout << "Enter filename to be read : ";
	getline( cin, filename );
	inFile.open( filename.c_str() , ios :: binary );

	if( inFile.is_open() ){
			if(inFile.seekg(index * RecordSize)){ // index * RecordSize is the offset of your record
					getline( inFile , theEmployee->EmployeeID ); // Note that you do not have an array anymore
					getline( inFile , theEmployee->EmployeeFirstName );
					getline( inFile , theEmployee->EmployeeLastName );
					getline( inFile , theEmployee->EmployeeDepartment );
					getline( inFile , theEmployee->EmployeePosition );
					inFile >> theEmployee->EmployeeWorkHours;
					inFile >> theEmployee->PayRate;
					inFile >> theEmployee->totalSalary;
			}
			inFile.close();
	}
}


but then it still cant read ?

sorry for my poor programming skills.. please be patient to teach me . and thanks again...
i can add new record and save all thing , but then if i reopen my driver program , it cannot read the record and display all the things already ..

show your modified code
the above 1 is modified 1 already . is wrong?
I wrote an example where I implemented the basic concept of random access file. Hope that helps:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;


struct Employee
{
  int EmployeeID;
  string EmployeeName;
	string EmployeeDepartment;
	string EmployeeDOB;
	string EmployeeAddress;
	int EmployeeWorkHours;
	int PayRate;
	int totalSalary;
};

fstream RecordFile;
const int RecordSize = 512;
const int UniqueIdPos = 0;
const int UniqueIdSize = 20;
const int RecordCountPos = UniqueIdSize + UniqueIdPos;
const int RecordCountSize = 20;
const int HeaderSize = UniqueIdSize + RecordCountSize;
int UniqueId = 0;
int RecordCount = 0;


bool readRecord(Employee *theEmployee , int index){

  bool ok = false;
  if(index < RecordCount) {

    if(RecordFile.seekg(index * RecordSize + HeaderSize)){

        RecordFile >> theEmployee->EmployeeID;
        RecordFile.ignore(1, '\n');
        getline(RecordFile, theEmployee->EmployeeName);
        getline(RecordFile, theEmployee->EmployeeDepartment);
        getline(RecordFile, theEmployee->EmployeeDOB);
        getline(RecordFile, theEmployee->EmployeeAddress);
        RecordFile >> theEmployee->EmployeeWorkHours;
        RecordFile >> theEmployee->PayRate;
        RecordFile >> theEmployee->totalSalary;
        ok = RecordFile.good();
    }
  }
  return ok;
}

void writeRecord(Employee *theEmployee , int index){

  if(RecordFile.seekp(index * RecordSize + HeaderSize)){
      ostringstream oss;

      oss << theEmployee->EmployeeID << endl << theEmployee->EmployeeName << endl
					<< theEmployee->EmployeeDepartment  << endl
					<< theEmployee->EmployeeDOB << endl << theEmployee->EmployeeAddress
					<< endl << theEmployee->EmployeeWorkHours << endl << theEmployee->PayRate
					<< endl << theEmployee->totalSalary << endl;
      RecordFile.width(RecordSize);
      RecordFile << left << oss.str();

      if(index >= RecordCount)
      {
        RecordCount = index + 1;
        if(RecordFile.seekp(RecordCountPos)){
          RecordFile.width(RecordCountSize);
          RecordFile << left << RecordCount;
        }
      }
  }
}

void addRecord(Employee *theEmployee){

    theEmployee->EmployeeID = UniqueId;
    ++UniqueId;
    if(RecordFile.seekp(UniqueIdPos)){
      RecordFile.width(UniqueIdSize);
      RecordFile << left << UniqueId;
    }

		cout << "Enter Name : ";
		getline( cin,theEmployee->EmployeeName );

		cout << "Enter Employee Department : ";
		getline( cin,theEmployee->EmployeeDepartment );

    writeRecord(theEmployee, RecordCount);
}

void deleteSpecificEmployeeRecord(Employee *theEmployee){ // if done theEmployee contains the deleted record

	int choice = 0;
	int SpecificEmployeeID = 0;
	bool found = 0;
	int foundIndex = 0;

	cout << "\tDelete Employee Record\n---------------------------------" << endl << endl
		 << "Enter Employee ID : "               ;
	cin >> SpecificEmployeeID;

	for( int i = 0 ; i < RecordCount ; i++ ){

	  if(readRecord(theEmployee, i)) {

      if(  theEmployee->EmployeeID == SpecificEmployeeID ){
        found = true;
        foundIndex = i;
        break;
      }
	  }
	}

	if( found == true ){
		cout << "\n\tRecord :\n---------------------" << endl
			 << "Employee ID   : "             << theEmployee->EmployeeID           << endl
			 << "Employee Name : "             << theEmployee->EmployeeName		   << endl
		     << "Employee Department    : "    << theEmployee->EmployeeDepartment   << endl
			 << "Employee Date Of Birth : "    << theEmployee->EmployeeDOB		   << endl
			 << "Employee Address    : "       << theEmployee->EmployeeAddress	   << endl
		     << "Employee Work Hours : "       << theEmployee->EmployeeWorkHours    << endl
			 << "Employee Pay Rate   : "       << theEmployee->PayRate			   << endl
			 << "Employee Salary     : "       << theEmployee->totalSalary          << endl << endl;
	}

	cout << "1. Delete Record " << endl
		 << "2. Cancel "        << endl;

	cin  >> choice;

	if( choice == 1){

    Employee e;
	  if(readRecord(&e, RecordCount - 1)) {

        writeRecord(&e, foundIndex);
        if(RecordFile.seekp((RecordCount - 1) * RecordSize + HeaderSize)){
            RecordFile.width(RecordSize);
            RecordFile << left << " ";
        }
        --RecordCount;
        if(RecordFile.seekp(RecordCountPos)){
          RecordFile.width(RecordCountSize);
          RecordFile << left << RecordCount;
        }
	  }
	}
	else if( choice == 2 ){

	}
}

int main()
{
	string filename;

	cout << "Enter name of the filename: ";
	getline( cin, filename );
	RecordFile.open( filename.c_str() , fstream::in | fstream::out | fstream::binary );
	if(RecordFile.is_open()) // if a file exists
	{
    if(RecordFile.seekg(UniqueIdPos))
      RecordFile >> UniqueId;
    if(RecordFile.seekg(RecordCountPos))
      RecordFile >> RecordCount;
	}
	else // This means the file doesn't exist and we have to do some preparations
	{
    RecordFile.open( filename.c_str() , fstream::out | fstream::trunc | fstream::binary ); // Note that we cannot use fstream::in since it would fail
    RecordFile.width(HeaderSize);
    RecordFile << left << " ";
    if(RecordFile.seekp(UniqueIdPos))
      RecordFile << UniqueId;
    if(RecordFile.seekp(RecordCountPos))
      RecordFile << RecordCount;
    RecordFile.close(); // Now the preparation is done and we can open the file regularly
    RecordFile.open( filename.c_str() , fstream::in | fstream::out | fstream::binary );
	}
	if(RecordFile.is_open())
	{
	  // Note: The following is for test purposes only. comment them in/out according to your needs
//	  Employee e0;
//	  deleteSpecificEmployeeRecord(&e0);
//	  Employee e;
//    readRecord(&e, 1);

//	  Employee e1;
//    addRecord(&e1);
//	  Employee e2;
//    addRecord(&e2);
//	  Employee e3;
//    addRecord(&e3);

	  RecordFile.close();
	}
	else
    cout << "Cannot open File " << filename << endl;

  return 0;
}
Mind you that's just one way to implement it. For simplicity I changed things like the unique id. So don't use this mindlessly. Further: if you change something within your record like EmployeeName to EmployeeFirstName/EmployeeLastName you cannot read the data based on the old record!
finally i got it .
@coder777 thanks for ur patiently for teaching me as well.
but say really until now . i still digesting the random access file .

it's too advance for me i think. but i trying to learning and keep learning right now.

for the last part which i done all already
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
void ModifySpecificEmployee(Employee *theEmployee){

	bool found = 0 ;
	int employeeID = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cin.ignore();
	cout << "\tModify Employee\n---------------------------------" << endl << endl
		 << "Enter Employee ID : ";
	cin  >> employeeID;

	for( int i = 0 ; i < RecordCount ; i++ ){
		if(readRecord(theEmployee, i)) {
			if(  theEmployee->EmployeeID == employeeID ){
				found = true;
				foundIndex = i;
			}
		}
	}
	if( found == true ){
		cout << "\n\tRecord :\n---------------------" << endl
			 << "Employee ID   : "             << theEmployee->EmployeeID           << endl
			 << "Employee First Name : "       << theEmployee->EmployeeFirstName	<< endl
			 << "Employee Last Name  : "       << theEmployee->EmployeeLastName	    << endl
		     << "Employee Department : "       << theEmployee->EmployeeDepartment   << endl
			 << "Employee Position   : "       << theEmployee->EmployeePosition		<< endl
		     << "Employee Work Hours : "       << theEmployee->EmployeeWorkHours    << endl
			 << "Employee Pay Rate   : "       << theEmployee->PayRate			    << endl
			 << "Employee Salary     : "       << theEmployee->totalSalary          << endl << endl
			 << "1. Change Employee First Name " << endl
			 << "2. Change Employee Last Name "  << endl
			 << "3. Change Department "   << endl
			 << "4. Change Position"      << endl
			 << "5. Change Work Hours "   << endl
			 << "6. Change Pay Rate "     << endl << endl;
		cout << "Enter Choice : ";
		cin  >> choice;

		switch( choice ){
		case 1:
			cin.ignore();
			cout << "Enter First Name : ";
			getline( cin,theEmployee->EmployeeFirstName );
			break;
		case 2:
			cin.ignore();
			cout << "Enter Last Name : ";
			getline( cin,theEmployee->EmployeeLastName );
			break;
		case 3:
			cin.ignore();
			cout << "Enter Employee Department : ";
			getline( cin,theEmployee->EmployeeDepartment );
			break;
		case 4:
			cin.ignore();
			cout << "Enter Employee Position : ";
			getline( cin,theEmployee->EmployeePosition );
			break;
		case 5:
			do{
				cin.ignore();
				cout << "Enter Work Hour : ";
				cin  >> theEmployee->EmployeeWorkHours;
				if( theEmployee->EmployeeWorkHours < 1 ){
					cout << "\nInvalid Input for Work Hours !" << endl;
				}
			}while( theEmployee->EmployeeWorkHours < 1 );

			theEmployee->totalSalary = theEmployee->EmployeeWorkHours * theEmployee->PayRate ;
			break;
		case 6:
			do{
				cin.ignore();
				cout << "Enter Pay Rate : ";
				cin  >> theEmployee->PayRate;
				if( theEmployee->PayRate < 1 )
					cout << "\nInvalid Input for Pay Rate !" << endl;
			}while( theEmployee->PayRate < 1 );
	
			theEmployee->totalSalary = theEmployee->EmployeeWorkHours * theEmployee->PayRate ;
			break;
		}
		cout << "Record has been modified !" << endl;
		writeRecord(theEmployee, RecordCount );
	}
	else{
		cout << "Record not found ! " << endl;
	}
}


why after i modified specific employee detail . and the record been modified right . but the id will get overwrite for 2 times . which mean the record i wan to modify is save inside the file is 2 SAME RECORD

cannot update the currently 1? so whats wrong with it?
I suspect line 86 should be writeRecord(theEmployee, foundIndex);
Last edited on
So is what cire said the solution?

One more thing: break the loop (on line 13) when found = true otherwise you read records uselessly
err , i added . but the last problem . why if i move to the 1 header file 2 cpp files. error would occur like this

1
2
3
4
1>main.obj : error LNK2005: "int UniqueId" (?UniqueId@@3HA) already defined in employee.obj
1>main.obj : error LNK2005: "int RecordCount" (?RecordCount@@3HA) already defined in employee.obj
1>main.obj : error LNK2005: "class std::basic_fstream<char,struct std::char_traits<char> > RecordFile" (?RecordFile@@3V?$basic_fstream@DU?$char_traits@D@std@@@std@@A) already defined in employee.obj
1>C:\Users\User\Desktop\trying\Debug\trying.exe : fatal error LNK1169: one or more multiply defined symbols found
my employee.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef EMPLOYEE_H 
#define EMPLOYEE_H 

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <conio.h>

using namespace std;

struct Employee{
	int EmployeeID;
	string EmployeeFirstName;
	string EmployeeLastName;
	string EmployeeDepartment;
	string EmployeePosition;
	int EmployeeWorkHours;
	int PayRate;
	int totalSalary;
};

fstream RecordFile;
int UniqueId = 0;
int RecordCount = 0;
const int RecordSize = 512;
const int UniqueIdPos = 0;
const int UniqueIdSize = 20;
const int RecordCountPos = UniqueIdSize + UniqueIdPos;
const int RecordCountSize = 20;
const int HeaderSize = UniqueIdSize + RecordCountSize;

bool readRecord(Employee * , int );
void writeRecord(Employee * , int );
void addRecord(Employee *);
void deleteSpecificEmployeeRecord(Employee *);
void displaySpecificEmployee(Employee *);
void displayAllEmployee(Employee *);
void displayParticularDepartment(Employee *);
void ModifySpecificEmployee(Employee *);

#endif 
put line 23 to 25 in one of the cpp files. In the header you write extern:
1
2
3
extern fstream RecordFile;
extern int UniqueId;
extern int RecordCount;
mind to explain what is
extern //external mean?
1
2
3
4
5
6
7
#include "employee.h"

fstream RecordFile;
int UniqueId = 0;
int RecordCount = 0;

bool readRecord(Employee *, int );


error
1
2
3
4
5
6
7
8
1>c:\users\user\desktop\trying\trying\employee.cpp(4): error C2374: 'UniqueId' : redefinition; multiple initialization
1>          c:\users\user\desktop\trying\trying\employee.h(21) : see declaration of 'UniqueId'
1>c:\users\user\desktop\trying\trying\employee.cpp(5): error C2374: 'RecordCount' : redefinition; multiple initialization
1>          c:\users\user\desktop\trying\trying\employee.h(22) : see declaration of 'RecordCount'
1>c:\users\user\desktop\trying\trying\employee.cpp(44): error C2088: '<<' : illegal for class
1>c:\users\user\desktop\trying\trying\employee.cpp(51): error C2440: '=' : cannot convert from 'int' to 'int'
1>c:\users\user\desktop\trying\trying\employee.cpp(55): error C2088: '<<' : illegal for class
1>c:\users\user\desktop\trying\trying\employee.cpp(165): error C2088: '<<' : illegal for class
get it after u gv me the link. problem solved ! thanks
Topic archived. No new replies allowed.
Pages: 12