Deleting Content from a file

Hi, I am attempting to write a program will prompt a user to input there name and address. The program gives the user the option to insert information (by pressing one), delete information(by pressing 2), display the information on the screen (by pressing 3) or exiting by pressing 4. I am trying to figure out how to delete the information (option 2) however I am having a difficult time figuring this out. So for example, the user would input someone's first name (ex- Jackie) and then all this information would automatically be deleted from the file

First Name: Jackie
Last Name: Doe
Address: 555 Golf Club Road
City: Pleasant Hill
State: CA
Zip: 94523

Could someone please help me ? Thank you

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
  /**
 •Write a program that will read in an array of records of people's names and addresses from the keyboard and then and writes that information to an output file.
 •Each record will consist of the following fields: first name 15 characters, last name 15 characters, street address 30 characters, city 20 characters, state 10 characters, zip long integer. Declare a structure called AddressBook to hold a record.
 •Read an array of records from the keyboard by prompting for data till the user enters a sentinel to quit. The program should keep track of the number of records read.
 •Store this information to a binary file.
 •Read from the binary file back to another array of records, and store this information to a text file. Left justify the information for each field.
 •Assume a maximum of 20 records.
 
 Output Run
 First Name: Jackie
 Last Name: Doe
 Address: 555 Golf Club Road
 City: Pleasant Hill
 State: CA
 Zip: 94523
  
 First Name: John
 Last Name: Anon
 Address:  10007 Side Street
 City: San Ramon
 State: CA
 Zip: 94582
  
 First Name: Sandy
 Last Name: Beach
 Address: 2345 Ocean Avenue
 City: Santa Cruz
 State: CA
 Zip: 95060
  
 First Name: June
 Last Name: Empire
 Address: 245 33rd Street
 City: New York
 State: NY
 Zip: 10017
 */
#include<iostream>
#include<fstream>
using namespace std;
//------------------------------------------------------------------------------------------
const int SIZE_OF_FIRST_NAME = 15, SIZE_OF_LAST_NAME = 15, STREET_ADDRESS = 30, CITY = 20, STATE = 10, ZIPCODE = 5;
//------------------------------------------------------------------------------------------
struct AddressBook
{
    char FirstName[SIZE_OF_FIRST_NAME],
         LastName[SIZE_OF_LAST_NAME],
         StreetAddress[STREET_ADDRESS],
         City[CITY],
         State[STATE];
     int Zip;

};
//------------------------------------------------------------------------------------------
int main ()
{
    int iteration = 0,
        option;
    AddressBook Address[20],
                Address2[20];
    string content,
           name,
           temp,
           file_name = "AddressBook.doc";
    char insert;
    fstream file;

   
    
    do
    {
        cout << "Select: ";
        cin >> option;
        cin.ignore();
       switch(option)
       {
   case 1:
        cout << "\n--------- Address Book: ---------\n";
        do
    {
        cout << "First Name: ";
        cin.getline(Address[iteration].FirstName, SIZE_OF_FIRST_NAME);
        cout << "\nLast Name: ";
        cin.getline(Address[iteration].LastName, SIZE_OF_LAST_NAME);
        cout << "\nStreet Address: ";
        cin.getline(Address[iteration].StreetAddress, STREET_ADDRESS);
        cout << "\nCity: ";
        cin.getline(Address[iteration].City, CITY);
        cout << "\nState: ";
        cin.getline(Address[iteration].State, STATE);
        cout << "\nZip Code: ";
        cin >> Address[iteration].Zip;
        
        iteration++;

        //This Section will prompt ask the user wants to re-input the data.
        cout << "\nPlease indicate if you would like\nto write a new record (Y/N) ";
        cin >> insert; insert = toupper(insert);
        cin.ignore();
        if(insert == 'Y'){cout << "\n---------------------------------\n\n";}
    }
    while (insert == 'Y');
    
    file.open("AddressBook.doc", ios::out | ios::binary);
    file.write(reinterpret_cast<char *>(&Address), sizeof(Address));
    
    //This section will close the file:
    file.close();
    
    //This section will open the file for the binary input:
    file.open("AddressBook.doc", ios::in | ios::binary);
    
    //This section will read the date that was previously inputted into the program:
    file.read(reinterpret_cast<char *>(&Address2), sizeof(Address2));
    file.close();
    
    file.open("AddressBook.doc", ios::out);
    
    //This section displays the contact stored inside the binary file:
               /***/
    for(int i = 0; i < iteration; i++)
    {
        file << "--------- " << Address2[i].FirstName << ' ' << Address2[i].LastName << " ---------";
        file << "\nFirst Name: " << Address2[i].FirstName;
        file << "\nLast Name: " << Address2[i].LastName;
        file << "\nAddress: " << Address2[i].StreetAddress;
        file << "\nCity: " << Address2[i].City;
        file << "\nState: " << Address2[i].State;
        file << "\nZip: " << Address2[i].Zip;
        file << endl;
    }
    file << "--------------------------------------\n";
    //Re-close file:
    file.close();
    cout << endl;
        break;
           case 2:
               file.open("/Users/kyledrewes/Library/Developer/Xcode/DerivedData/Address_Book-apkdrrzyaohdlieockksffoggadr/Build/Products/Debug/AdressBook.doc", ios::in);
               if(file.is_open())
               {
                   cout << "\nWhich name would you\nlike to delete ? ";
                   getline(cin,name);
                   
                   while(!file.eof())
                   {
                       getline(file,content);
                       
                       if(content.find(name) == string::npos){temp += content;}
                       content.clear();
                   }
                   file.close();
                   file.open("/Users/kyledrewes/Library/Developer/Xcode/DerivedData/Address_Book-apkdrrzyaohdlieockksffoggadr/Build/Products/Debug/AdressBook.doc",ios::out|ios::trunc);
                   if(file.is_open()){file << temp; file.close();}
                   else{cout << "\nFile is not open\n\n";}
               }
               else{cout << "\nFile is not open\n\n";}
               break;
               
           case 3:
               //Display Content
               for (int i = 0; i < iteration; i++)
               {
                   cout << "-------------- " << Address2[i].FirstName << ' ' << Address2[i].LastName << " --------------";
                   cout << "\nFirst Name: " << Address2[i].FirstName;
                   cout << "\nLast Name: " << Address2[i].LastName;
                   cout << "\nAddress: " << Address2[i].StreetAddress;
                   cout << "\nCity: " << Address2[i].City;
                   cout << "\nState: " << Address2[i].State;
                   cout << "\nZip: " << Address2[i].Zip;
                   cout << endl << endl;
               }
               break;
           default:
               cout << "\nInvalid entry, please re-enter.";
               break;
       }
    }while(option!=4);
    return 0;
}
//------------------------------------------------------------------------------------------
This is one possible approach:
https://www.geeksforgeeks.org/cprogram-to-delete-the-content-of-a-binary-file/

Another one is to read the data into an array or vector etc, instead of creating a new file.

Another one is to have each record include a flag/attribute/field to indicate whether the record is current or deleted. That way there is a permanent archive. The actual permanent deletions from the file record can then be handled as above in a 'mass' cleanup.
Ok thanks agentry, I'll check it out and see what the best options is.
Using a text file presents problems with accessing information like what you're trying to do...mainly that you have to read through the entire thing and do a bunch of comparisons to find something.

IMO you'd be better off using a binary file for this and storing the values as members of a data structure. That way you can access individual listings in the file and read them all at once, instead of having to search through a bunch of stuff.

If you absolutely have to use a plain txt file for this (as in, homework assignment) then you will need to use a lot of for loops to read in the information from the file, and compare it to the informaton stored in your variables.
Re-factoring the code into functions etc, perhaps something like:

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
#include <iostream>
#include <fstream>
#include <cctype>

constexpr size_t SIZE_OF_FIRST_NAME = 15, SIZE_OF_LAST_NAME = 15, STREET_ADDRESS = 30, CITY = 20, STATE = 10, ZIPCODE = 5;
constexpr size_t MAXADDR {20};

struct Address {
	char FirstName[SIZE_OF_FIRST_NAME] {},
		LastName[SIZE_OF_LAST_NAME] {},
		StreetAddress[STREET_ADDRESS] {},
		City[CITY] {},
		State[STATE] {};
	int Zip {};
};

struct AddressBook {
	Address addr[MAXADDR] {};
	size_t no_addr {};
	bool saved {true};
};

char toupper(char ch)
{
	return static_cast<char>(std::toupper(static_cast<unsigned char>(ch)));
}

void addAddress(AddressBook& ab)
{
	for (char again {'Y'}; ab.no_addr < MAXADDR && toupper(again) == 'Y'; ) {
		std::cout << "First Name: ";
		std::cin.getline(ab.addr[ab.no_addr].FirstName, SIZE_OF_FIRST_NAME);

		std::cout << "\nLast Name: ";
		std::cin.getline(ab.addr[ab.no_addr].LastName, SIZE_OF_LAST_NAME);

		std::cout << "\nStreet Address: ";
		std::cin.getline(ab.addr[ab.no_addr].StreetAddress, STREET_ADDRESS);

		std::cout << "\nCity: ";
		std::cin.getline(ab.addr[ab.no_addr].City, CITY);

		std::cout << "\nState: ";
		std::cin.getline(ab.addr[ab.no_addr].State, STATE);

		std::cout << "\nZip Code: ";
		std::cin >> ab.addr[ab.no_addr].Zip;

		ab.saved = false;

		if (++ab.no_addr < MAXADDR) {
			std::cout << "\nAdd another new record (Y/N): ";
			std::cin >> again;
			std::cin.ignore();
		}
	}

	if (ab.no_addr >= MAXADDR)
		std::cout << "Limit reached!\n";
}

void remove(AddressBook& ab)
{
	std::string first, last;

	std::cout << "\nWhich name would you like to delete? (first last)";
	std::cin >> first >> last;

	for (size_t i = 0; i < ab.no_addr; ++i)
		if (ab.addr[i].FirstName == first && ab.addr[i].LastName == last) {
			for (size_t j = i + 1; j < ab.no_addr; ++j)
				ab.addr[j - 1] = ab.addr[j];

			--ab.no_addr;
			ab.saved = false;
			return;
		}

	std::cout << "\nNot found\n";
}

std::ostream& operator<<(std::ostream& os, const AddressBook& ab)
{
	for (int i = 0; i < ab.no_addr; ++i) {
		os << "-------------- " << ab.addr[i].FirstName << ' ' << ab.addr[i].LastName << " --------------";
		os << "\nFirst Name: " << ab.addr[i].FirstName;
		os << "\nLast Name: " << ab.addr[i].LastName;
		os << "\nAddress: " << ab.addr[i].StreetAddress;
		os << "\nCity: " << ab.addr[i].City;
		os << "\nState: " << ab.addr[i].State;
		os << "\nZip: " << ab.addr[i].Zip;
		os << "\n\n";
	}

	return os;
}

int main()
{
	const std::string file_name_doc = "AddressBook.bin",
		file_name_txt = "AddressBook.txt";

	int option {};
	AddressBook Address {};
	std::fstream file;

	do {
		std::cout << "1. Read from file (binary)\n";
		std::cout << "2. Write to file (binary)\n";
		std::cout << "3. Write to file (text)\n";
		std::cout << "4. Insert\n";
		std::cout << "5. Delete\n";
		std::cout << "6. Display\n";
		std::cout << "7. Exit\n\n";
		std::cout << "Select: ";
		std::cin >> option;
		std::cin.ignore();

		switch (option) {
			case 1:
				// read ab from file as binary
				if (char cont {}; !Address.saved) {
					std::cout << "This will overwrite local data. Continue (Y/N): ";
					std::cin >> cont;
					std::cin.ignore();

					if (toupper(cont) == 'N')
						break;
				}

				file.open(file_name_doc, std::ios::in | std::ios::binary);
				file.read(reinterpret_cast<char*>(&Address), sizeof(Address));
				file.close();
				break;

			case 2:
				// Write ab to file as binary
				Address.saved = true;
				file.open(file_name_doc, std::ios::out | std::ios::binary);
				file.write(reinterpret_cast<char*>(&Address), sizeof(Address));
				file.close();
				break;

			case 3:
				// write ab as text
				file.open(file_name_txt, std::ios::out);
				file << Address << '\n';
				file.close();
				break;

			case 4:
				// Insert new data
				addAddress(Address);
				break;

			case 5:
				// delete an entry
				remove(Address);
				break;

			case 6:
				// display
				std::cout << Address << '\n';
				break;

			case 7:
				// Exit
				break;

			default:
				std::cout << "\nInvalid entry, please re-enter.\n";
				break;
		}
	} while (option != 7);
}

Last edited on
Topic archived. No new replies allowed.