Deleting Entries from a Structured Array

Hi there, i have an assignment, and i need to create a monthly expenditure. I have managed to get alot done, a fully functioning menu and all the functions. Im stuck when it comes to deleting an entry

I have been using structured arrays to store data, ive posted all my code, i thought it be easier for help, sorry for the massive post.

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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
using namespace std;

int i;
int count;
int userChoice;
string temp;

int newExpenses();
int newIncome();
void menuExpenses();
void menuIncome();
void mainMenu();
void monthlyExpenses();
void monthlyIncome();
void deleteEntry();


int main()
{

	string line;
	ifstream myfile ("counter.txt");
	if(myfile.is_open())
	{
		while(!myfile.eof())
		{
			getline(myfile,line);
			temp=line;
		}
		myfile.close();
	}


	count=atoi(temp.c_str());
	
	do{
	mainMenu();
	}while(userChoice != 1 || userChoice != 2);

	return 0;
}

struct entry{
	int ID;
	string date;
	string item;
	string price;
	string category;
}entries[100];

void mainMenu()
{
	cout<<"Monthly Expenditure"<<endl<<endl<<endl;
	cout<<"Main Menu"<<endl<<endl;
	cout<<"Income [1]"<<endl<<"Expenses [2]"<<endl<<"View Monthly Income [3]"<<endl<<"View Monthly Expenses [4]"<<endl<<"Delete Entry [5]"<<endl;
	cin>>userChoice;

	if(userChoice == 1)
	{	
		system("cls");
		menuIncome();
	}	
	
	else if(userChoice == 2)
	{
		system("cls");
		menuExpenses();
	}	

	else if(userChoice == 3)
	{
		system("cls");
		monthlyIncome();
	}

	else if(userChoice == 4)
	{
		system("cls");
		monthlyExpenses();
	}

	else if(userChoice == 5)
	{
		system("cls");
		deleteEntry();
	}

	else
	{
		system("cls");
		cout<<"Invalid input, please select again [1] [2] [3] [4]";
	}
}

void monthlyIncome()
{
	string line;
	ifstream myfile ("Income.txt");
	if(myfile.is_open())
	{
		while(!myfile.eof())
		{
			getline(myfile,line);
			cout<<line<<endl;
		}
		myfile.close();
	}

}


void monthlyExpenses()
{
	string line;
	ifstream myfile ("Expenses.txt");
	if(myfile.is_open())
	{
		while(!myfile.eof())
		{
			getline(myfile,line);
			cout<<line<<endl;
		}
		myfile.close();
	}

}

void menuExpenses()
{
int userChoice2=0;

do{
	cout<<"Expenses"<<endl<<endl;
	cout<<"Add Entry (1)"<<endl;
	cout<<"Sort Ascending (2)"<<endl;
	cout<<"Sort Descending (3)"<<endl;
	cin>>userChoice2;

	if(userChoice2 == 1)
	{
		system("cls");
		newExpenses();
	}
	else if(userChoice2 == 2)
	{	
		system("cls");
		//Sort code
	}
	else if(userChoice2 == 3)
	{	
		system("cls");
		//Sort code
	}
	else
	{
		system("cls");
		cout<<"Invalid input, please select again [1] [2] [3]"<<endl<<endl;
		userChoice2=0;

	}
}while(userChoice2==0);

}		

void menuIncome()
{
int userChoice3=0;

do{

	cout<<"Income"<<endl<<endl;
	cout<<"Add Entry (1)"<<endl;
	cout<<"Sort Ascending (2)"<<endl;
	cout<<"Sort Descending (3)"<<endl;
	cin>>userChoice3;

	if(userChoice3 == 1)
	{
		system("cls");
		newIncome();
	}
	else if(userChoice3 == 2)
	{
		system("cls");
		//Sort code
	}
	else if(userChoice3 == 3)
	{
		system("cls");
		//Sort code
	}
	else
	{
		system("cls");
		cout<<"Invalid input, please select again (1) (2) (3)"<<endl<<endl;
		userChoice3=0;
	}
}while(userChoice3==0);

}

int newIncome()
{
		cout<<"Income"<<endl<<endl;
		cout<<"New Entry"<<endl;

		entries[count].ID=count;
		cout<<"Date: ";
		cin>>entries[count].date;
		cout<<"Item: ";
		cin>>entries[count].item;
		cout<<"Price: ";
		cin>>entries[count].price;
		cout<<"Category: ";
		cin>>entries[count].category;
		cout<<endl;

		ofstream fout;
		
		fout.open("Income.txt", ios::app);

		fout<<entries[count].ID<<"     "<<entries[count].date<<"     "<<entries[count].item<<"     "<<entries[count].category<<"     "<<entries[count].price<<endl;
		fout<<flush;
		fout.close();


		
count++;


ofstream fout1;

fout1.open ("counter.txt");

fout1<<count;
fout1<<flush;
fout1.close();
return 0;
}		

int newExpenses()
{
	
		cout<<"Expenses"<<endl<<endl;
		cout<<"New Entry"<<endl;

		entries[count].ID=count;
		cout<<"Date: ";
		cin>>entries[count].date;
		cout<<"Item: ";
		cin>>entries[count].item;
		cout<<"Price: ";
		cin>>entries[count].price;
		cout<<"Category: ";
		cin>>entries[count].category;
		cout<<endl;

		ofstream fout;
		
		fout.open("Expenses.txt", ios::app);
		
		fout<<entries[count].ID<<"     "<<entries[count].date<<"     "<<entries[count].item<<"     "<<entries[count].category<<"     "<<entries[count].price<<endl;
		fout<<flush;
		fout.close();
	

	
count++;

ofstream fout1;

fout1.open ("counter.txt");

fout1<<count;
fout1<<flush;
fout1.close();
return 0;
}	

void deleteEntry()
{
	int choice;
	int i;

	cout<<"What entry do you wish to delete?: "<<endl;
	cin>>choice;
	
	if(choice >= 0 && choice <= 100)
	{
		for(i=choice;i<100;i++)
		{
		entries[i] = entries[i + 1];
		}
	}
	else
	{
		cout<<"Invalid Entry";
	}
}


What my tutor suggested was to use a counter, and then save the counter also in a text file, so when i reopen the console, the counter doesnt reset to 0

Is there a simpler way to be able to delete one of these entries? each entry has an ID

(new to programming, still learning at uni)
I don't understand how a counter written to a file is going to help you. It looks like you are trying to redo what a std::vector already provides (you are copying every entry forward if something in the middle is deleted). Since you have an array, you can't really "erase" an entry but you could simply clear it. Does it matter if there is an unused entry in the middle? It seems to me that this program should allow for dynamic expansion of the array anyhow. You are currently limited to 100. I would recommend using a std::deque personally. if you have a std::deque then you can build the array of entries dynamically and simply call its member functions to add or delete entries. It will manage the memory for you and keep track of the size of the array. If you aren't ready to get into those classes yet, consider maintaining the array such that you can simply clear the entry and leave it in the middle. You could make it work that way as well, for starters. For this program to be useful, eventually it needs to be more dynamic.

By the way, thanks for posting neat code with tags and proper indenting. The indenting is a bit off in spots but the format of the post is better than many others.
Last edited on
This statement is wrong. You forgot the [5].
cout<<"Invalid input, please select again [1] [2] [3] [4]";

This is also wrong. The program may exit prematurely because you aren't including all of the possibilities in the do..while conditions.
}while(userChoice != 1 || userChoice != 2);

The file i/o, in general, is still incoherent. I'm not sure what your plans are for that. Are you planning on reading the data back in to initialize the program? Reading the counter from a file isn't helpful at all unless you are planning on reading all of the previously entered records. Personally, I would output each record of the array to a binary file prior to exiting. In fact that would be an advantage of using vector instead of deque. Vector might be slightly less efficient if you are inserting and deleting lots of records in the middle but would maintain records in a contiguous block of memory that could easily be written to a binary file and easily read back in at the end. In that case you could develop a structure that contains a header (including the count of records) and a body where the body is the array of records. When the program starts, you read the file header first to determine how many records are present. Then you validate the file size based on how many records are present. Finally, you read the data straight into the array.



Thanks for the reply kempo :)

You seem very skilled in programming, to be honest, you have lost me on some stuff lol, i understand bits of what you are telling me, my tutor at uni mentioned dynamic memory allocation, but we havent been taught anything on the subject.

Let me try again. When your program initializes it reads a counter. It also builds the 100 element entries array which is not initialized. What good is it to read in a counter that only tells you how many things were in the array during the last execution of the program? The array is currently full of garbage. In order to make use of a counter you need to be able to re-initialize the array from a file as well. The counter by itself is useless. In fact it'll cause problems because you might think that there are 20 records when in reality none of them are even initialized.
Topic archived. No new replies allowed.