After searching and obtaining a record, how can one erase the found record from a file ?

I have written this method to search a row (line of comma separated strings) from a text file, once found, the contents of the record should be erased. Where is the mistake and how do i improve it ?

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
void delete_record (){

std::string line = "";

   std::string searchOwnerName = "";
	std::string KRANumber = "";
	
std::string::size_type offset;  
	
	//std::vector<std::string>Edit;    
	//std::vector< vector<std::string> >DeleteRecord;

    std::fstream inFile("Land Registry.txt");  //open text file
    
    std::cout << "Please enter search string: ";
    std::cin >> searchOwnerName;
	 std::cout << "Enter search Kra PIN: ";
	 cin>>KRANumber;

	if (!inFile)  {
	    
        std::cout << "File not opened\n"; return;
	      }

	else
    {
        while (std::getline(inFile, line))  //reading file line by line
   
ofstream out ("New Register.txt");          

	if ((offset = line.find (searchOwnerName, 0)) && (offset = line.find (KRANumber,0) !=string::npos))
	
                std::cout <<"\n"<< searchOwnerName <<"of KRA Number"<<KRANumber<< "record found at: \n\n" << line << '\n';

			
			cout<<"/nThis record is about to be erased from register. Press Enter to delete";

			
		inFile.close ();
        out.close ();

		remove ("Land Registry.txt");
		rename ("New Register.txt", "Land Registry.txt"); 

cout<<"\nOld record has been deleted and new records file created\n";

		}
system ("pause");

return;
    
   }
}



If i wanted to use the same function, after searching and finding a record,how can i be able to modify the contents of the found line (editing parts of the record found) or even adding some content to that comma separated line at the end of the line ?
Last edited on
closed account (E0p9LyTq)
After searching and obtaining a record, how can one erase the found record from a file ?


The easiest way is to write the read data back out to the file (or a temp file), omitting the record(s) you want excluded.

How you implement that is up to you.
closed account (48T7M4Gy)
http://www.cplusplus.com/forum/general/193596/
+1 FurryGuy
+1 kemort

to add to what @FurryGuy said, you may make a temp file, record all the observation, skip the one you want to delete, then delete the original file and rename the temp file to original file name....

also there are many online tutorial for this stuff if you get confused
What IS the mistake that you think you have?
Last edited on
@ Little Captain .....i have edited the method (kindly look up there) .....

The problem is, when the record from file is found, the Land Registry.txt contents are all erased, yet the New Register.txt created contains no data - therefore i loose all data in the first file and are not written to the second file.
Last edited on
line 27 to 29

firstly the ofstream out ("New Register.txt"); should be outside the while loop

secondly there's no while loop without brackets :)
programmer007 ...... i have made the two amendments. However, the New Register.txt remains blank yet the Land Registry.txt contents have are all truncated.
Last edited on
You're all making a mistake.

1) Load ALL data into memory
2) Modify data in memory
3) Overwrite file with data from memory

This only requires some very simple data structures (an array or vector of structs) and a few functions to read and write the data from/to stream.

This is the simplest and easiest way to write the code correctly.
Thanks Duoas.....it is you who has made me reach this level in programming
I have now written this function to modify/ overwrite a record from a textfile ....The stringstream is doing, the program is running and i wonder what part should i use fresh user data to modify the content of the sstream then save the modified record. Problem is at the end of function.

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
#include <fstream> //for ifstream and ofstream
#include <iostream>
#include <string> //for the string class
#include <sstream> //for stringstream
using namespace std; 

struct LandDetails { //struct to contain my variables
	string Surname, OtherNames, LandNum,KraPin,OwnerIdCard, address,LandCounty, LandDist, LandDiv, Landloc, LandSubloc;

};


void GetAVariableFromATextFile(LandDetails& reader,LandDetails&enter )
{
	
	 std::string searchOwnerName = "";
	std::string KRANumber = "";
	
	ifstream textFile ("Registration.txt"); //opening the text file in read mode
	

	if( textFile.is_open() )
	{
		std::string::size_type offset;
		
		string variableFromATextFileAsString;
		getline( textFile, variableFromATextFileAsString ); //parsing the file
		
		std::cout << "Please enter an individual's name to search from the register: ";
   getline (cin, searchOwnerName);
   
   
	std::cout << "Enter his/her Kra PIN: ";
 getline (cin, KRANumber);

		if ((offset = variableFromATextFileAsString .find (searchOwnerName, 0)) && (offset = variableFromATextFileAsString .find (KRANumber,0) !=string::npos))
		{
			if (!offset ) cout<<"No matching record found !";

			else

		{          
			std::cout <<"\n"<<searchOwnerName<<" of KRA Number "<< KRANumber<<" record found at: \n\n"<< variableFromATextFileAsString << '\n';
			
		
	textFile.close();
		stringstream ss(variableFromATextFileAsString);
		ss >>reader.Surname>>reader.OtherNames>>reader.LandNum>>reader.KraPin>>reader.OwnerIdCard
		>>reader. address>>reader.LandCounty>>reader.LandDist>>reader.LandDiv>>reader.Landloc>>reader. LandSubloc;
	
	cout<<"\nDisplaying the data read into stream (i want to overwrite this)\n\n"<<endl;
		cout<<variableFromATextFileAsString;

		//ostringstream writer;
		
	//Replacing and old record with new data it to be used later (put the value on the first line)
	
	
ofstream openFile ("Registration.txt", ios::app);


cout<<"\n\nEnter Surname of new record holder to replace the above data holder\n";
getline (cin, enter.Surname);



cout<<"Enter other names of current holder\n";
getline (cin, enter.OtherNames);


cout<<"Enter Land number\n";
     getline (cin, enter.LandNum);
	 
cout<<"Enter owner KRA pin\n";
	getline (cin, enter.KraPin);
	
cout<<"Enter Owner id card number\n";
getline (cin, enter.OwnerIdCard);

cout<<"Enter owner address\n";
		getline (cin, enter.address);
		
cout<<"Enter Land county\n";
	
	getline (cin, enter.LandCounty);

		cout<<"Enter Land district\n";
	getline (cin, enter.LandDist);
	

cout<<"Enter Land division\n";
getline (cin, enter.LandDiv);

cout<<"Enter land location\n";
	getline (cin, enter.Landloc);

cout<<"Enter Land sub-location\n\n";
getline (cin, enter.LandSubloc);

ss<<enter.Surname<<", "<<enter.OtherNames<<", "<<enter.LandNum<<", "<<enter.KraPin<<","<<enter.OwnerIdCard
<<enter.address<<","<<enter.LandCounty<<","<<enter.LandDist<<","<<enter.LandDiv<<","<<enter.Landloc<<enter.LandSubloc;

	//"The problem is down here, the ss has not been modified to take the new data (instead the stream has lost data) which should be written to text file\n thus replacing the old record";
//....Also, how do i overwrite the record now that the file is open (by ofstream openFile )
	cout<<ss;

	cout<<"\nThe problem is up here ^, the ss has not been modified to take the new data \n (instead the stream has lost data) which should be written to text file \nthus replacing the old record\n\n";

	textFile.close();
	system ("pause");
	
}
		cout<<endl;
			}
	}

}

	int main (){

LandDetails testing; // objsects to be used to initialize the struct variables
LandDetails save;

GetAVariableFromATextFile (testing, save);


system ("pause");
		return 0;



i am using the above to read the text file below:

1
2
3
4
5
6
7
8
9
10
11

SURNAME: Elijah,OTHER NAMES: Mwangi Maina,LAND NUM: 24269010,KRA PIN: xxxxx,ID NUMBER: yyyyy,ADDRESS: n/a,COUNTY: n/a,DIST: n/a,DIV: n/a,LOC: n/a,SUBLOC: n/a

SURNAME: Stephen,OTHER NAMES: Muhoro Maina,LAND NUM: 123456,KRA PIN: cnnvn,ID NUMBER: nvndh,ADDRESS: jfcj,COUNTY: fjj,DIST: fj,DIV: j,LOC: fjjf,SUBLOC: fjfj

SURNAME: Herman,OTHER NAMES: Gitau Maina,LAND NUM: 098765,KRA PIN: sgd,ID NUMBER: dhf,ADDRESS: dfhjf,COUNTY: fjgy,DIST: du,DIV: turfu,LOC: rfutr,SUBLOC: rut

SURNAME: George,OTHER NAMES: Maina Gitau,LAND NUM: 123,KRA PIN: afsg,ID NUMBER: ddhh,ADDRESS: hjfj,COUNTY: fjgfj,DIST: fjgfj,DIV: fgjgfj,LOC: dyrt,SUBLOC: rutjug

SURNAME: Jane,OTHER NAMES: Njeri Mwangi,LAND NUM: 3456,KRA PIN: asg,ID NUMBER: sg,ADDRESS: dh,COUNTY: h,DIST: dfhh,DIV: fhfj,LOC: dhg,SUBLOC: wsdh

closed account (48T7M4Gy)
Adopt the conventional dbf serialisation style. Incorporate an additional attribute in the record to flag whether or not it is deleted so that records can be temporarily filtered as deleted or permanently deleted in the refiling phase method.
Last edited on
Topic archived. No new replies allowed.