Banking total money

I have a problem in which my functions aren't working on line 126 and 155.
I have been trying to make it read it and properly display the total money of someone, but to no avail. Here is my whole code for context. Also I used text files called "Money.txt" and "Accounts.txt" where the money document displays total amount of money for a person.
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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;

int display(char& anwser);
void N_account(char& anwser, string& name, char& anwser3);
int Exist(string& name_search, char& anwser, string name_from_file, char& anwser2, float& money_deposit);
void deposit(double money_deposit, float& total_money, char& anwser3);
void withdraw(char& anwser, char& anwser2, float& money_deposit, float& total_money, char& anwser3, float& withdraw_money);
void view(string& name_search, string name_from_file, char& anwser2, float& total_money, char& anwser3, char& anwser);



int main()
{
	int start_money;
	float money_deposit, withdraw_money, total_money=0;
	string name, name_search, name_from_file;
	char anwser, anwser2, anwser3;
	display(anwser);
	if (anwser == '1')
	{
		N_account(anwser, name,anwser3);
	}
	if (anwser == '2')
	{
		Exist(name_search, anwser, name_from_file, anwser2, money_deposit);
	}
	if (anwser2 == '1')
	{
		deposit(money_deposit, total_money,anwser3);
	}
	if (anwser2 == '2')
	{
		withdraw( anwser, anwser2,total_money,money_deposit,anwser3,withdraw_money);
	}
	if (anwser2 == '3')
	{
		view(name_search, name_from_file, anwser2, total_money,anwser3,anwser);
	}

}

int display(char& anwser)
{

	cout << setw(65) << "=================" << endl;
	cout << setw(65) << "Banking Managment" << endl;
	cout << setw(65) << "=================" << endl;
	cout << setw(60) << "1.New account" << endl;
	cout << setw(65) << "2.Existing account" << endl;
	cin >> anwser;
	return 0;
}

void N_account(char& anwser, string& name,char & anwser3)
{

	ofstream outfile;
	outfile.open("Accounts.txt", std::ofstream::out | std::ofstream::app);
	cout << "Enter in first and last name for new account:";
	cin.ignore();
	getline(cin, name);
	outfile << name;
	outfile << endl;
	cout << "Account added" << endl;
	outfile.close();
	cout << "Anything else you wish to do? press Y for yes or N for no: ";
	cin >> anwser3;
	if (toupper(anwser3) == 'Y')
	{
		
		main();
	}
	else
	{
		cout << "Goodbye!" << endl;
		system("pause");
		exit(1);
	}
	

}

int Exist(string& name_search, char& anwser, string name_from_file, char& anwser2, float& money_deposit)
{
	ifstream infile;
	infile.open("Accounts.txt");
	cout << "Enter in your account:";
	cin.ignore();
	getline(cin, name_search);
	while (getline(infile, name_from_file))//This scans the Accounts file and looks for the whole name of an existing account
	{
		if (name_from_file == name_search)
		{
			cout << "Account found: " << name_search << endl;
			cout << "Choose what you would like to do" << endl;
			cout << setw(56) << "1.Deposit" << endl;
			cout << setw(57) << "2.Withdraw" << endl;
			cout << setw(61) << "3.View account" << endl;
			cin >> anwser2;
			return 0;
		}

	}
	infile.close();

}

void deposit(double money_deposit,float & total_money,char & anwser3)
{

	ofstream O_file;
	O_file.open("Money.txt", std::ofstream::out | std::ofstream::app);
	cout << "Enter in how much you would like to deposit: ";
	cin >> money_deposit;
	if (money_deposit < 0)
	{
		cout << "Error!" << endl;
		system("pause");
		exit(1);
	}
	printf("%f\n", total_money);
	total_money = total_money + money_deposit;//problem here
	printf("%f\n", total_money);
	//O_file << money_deposit;
	O_file << total_money;
	O_file << endl;
	O_file.close();
	cout << "Anything else you wish to do? press Y for yes or N for no: ";
	cin >> anwser3;
	if (toupper(anwser3) == 'Y')
	{
	
		main();
	}
	else
	{
		cout << "Goodbye!" << endl;
		system("pause");
		exit(1);
	}

}

void withdraw( char& anwser, char& anwser2, float& money_deposit, float& total_money,char & anwser3,float &withdraw_money)
{
	
	ofstream O_file;
	O_file.open("Money.txt", std::ofstream::out | std::ofstream::app);
	cout << "Enter in how much you would like to withdraw:";
	cin>>withdraw_money;
	total_money = total_money - withdraw_money;//problem here
	O_file << total_money;
	O_file << endl;
	O_file.close();
	cout << "Anything else you wish to do? press Y for yes or N for no: ";
	cin >> anwser3;
	if (toupper(anwser3) == 'Y')
	{
	
		main();
	}
	else
	{
		cout << "Goodbye!" << endl;
		system("pause");
		exit(1);
	}

}

void view(string& name_search, string name_from_file, char& anwser2,float & total_money,char & anwser3,char & anwser)
{
	ifstream infile, I_file;
	infile.open("Accounts.txt");
	I_file.open("Money.txt");
	while (getline(infile, name_from_file))
	{
		if (name_search == name_from_file)
		{
			cout << "Account: " << name_from_file << endl;
			cout << "Balence: " << total_money << endl;
		}
	}
	infile.close();
	I_file.close();
	cout << "Anything else you wish to do? press Y for yes or N for no: ";
	cin >> anwser3;
	if (toupper(anwser3) == 'Y')
	{
		
		main();
	}
	else
	{
		cout << "Goodbye!" << endl;
		system("pause");
		exit(1);
	}
}


Accounts.txt have the following:
1
2
3
4
5
6
John Doe
Jane Doe
Travis Scott
William Smith
Patrick Michaels
Courtney Desmond

Money.txt has the following:
1
2
3
4
5
6
115
145
76
246.75
89.54
127.32
It might be easier for you to use just one .txt and write it out like this:

John Doe 115
Jane Doe 145
Travis Scott 76
William Smith 246.75
Patrick Michaels 89.54
Courtney Desmond 127.32


Secondly, you're trying to work with your accounts on the fly from the .txt files. I personally find it a lot easier to make a struct and hold all the accounts, then I don't have to deal with those text files anymore.

Finally, the bigger issue:

Line 19 - total_money is set to 0 and you NEVER change it. Once they tell you their names, so this should be added into the function "Exist", you should see how many lines it took to get to their name. Use that number to skip over the same amount of lines in "Money.txt" and get the account's balance.

In this whole program, you never even tried to grab the amount of money each person has, it's simply always 0.

Also, every time this program outputs to the .txt files, it does it on the last line where there is already information, make a new line.

EDIT:

Also, notice how in the function deposit, you haven't changed anyone's balance, you've simply created a new balance! You took in the input, added 0 to it (total_money), then you outputted it to the file, but WHERE it goes in the file is important, because I assume there's a correlation with line number and account holder.

Also, avoid using system calls like in line 122
Last edited on
Hello Deadweight77,

I do not know if this is homework or something else. It would help to know if you are stuck with the input files or if you could change them?

zapshe has made some very good points that need addressed.

For the input file another option would be:

John Doe,115
Jane Doe,145
Travis Scott,76
William Smith,246.75
Patrick Michaels,89.54
Courtney Desmond,127.32


This way you could read the file with:
1
2
3
std::getline(inFile, name, ',');
inFile >> balance;
inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. 


Since I mentioned it early, your use if std::cin.ignore(); is not the best way to use this. Without any parameters the statement will ignore the defaults of one character or the new line (\n) whichever comes first. The problem is should the input buffer have more than one character in it the anything after the first character will be left in the input buffer. That could be a problem especially if followed by a "getline".

Using inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>. or the above "inFile" will clear more than one character from the input buffer. The first parameter of "ignore" is just a large number. Some people use "1000" or "10000" and this should work most of the time. To be sure that the entire input buffer is cleared std::numeric_limits<std::streamsize>::max() will return the largest possible number available for the computer, operating system and header files that are being used. This is because different computers will have different set ups and a different size for the input buffer. This just makes sure that you are getting the largest possible number and is the most often used and suggested.

.ignore works on a stream. This could either be either "std::cin" or a file stream.

Before I could get the code to run I had to fix a two small errors. When I tried to compile your original code I received three warnings, but no errors.

In the function "deposit" "total_money" is defined as a "float", but "money_deposit" is defined as a "double". Converting from a "double" to a "float" could cause loss of data as a "float" is smaller than a "double", (in simple terms). You are better to use "double" for the floating point type.

Also the variable "start_money" is defined, but never used.

When the program ran I noticed that the if statements in "main" are a problem. Being separate if statements each one is checked even if it does not need to be. "if/else if" statements would work better or maybe even a switch.

The problem came at if (anwser2 == '1'). BTW the proper spelling is "answer". Your "s" and "w" are reversed. When the program ran it stopped here telling that "answer2" is an uninitialized variable. And it has never received a value before it is used.

Another thing I noticed is that you are passing variables to functions by reference, but some of these variables are never used by the function. Most of these variables should be defined in the function and returned if needed.

The function "display", or what should be "mainMenu" returns an "int" but is never used in "main". You are also passing a variable by reference and that could be a problem.

As I was working on the "mainMenu" I realized that you are presenting numbers for your choices, but taking in this number as a "char". The number "1" and the character "1" are two different values. "1" has the ascii value of one, but the character "1" has the ascii value of "49". This is not a big problem, but it does not work to your advantage.

This is something I was working with for the main menu:
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
int display() // <--- Would be better as "mainMenu".
{
	constexpr size_t WIDTH{ 50 };

	int choice{};
	//std::string spaces(WIDTH, ' '); // <--- An alternative.

	do
	{
		CLS;

		std::cout << "\n\n";
		std::cout << std::setw(WIDTH) << ' ' << "=================" << '\n';
		std::cout << std::setw(WIDTH) << ' ' << "Banking Managment" << '\n';
		std::cout << std::setw(WIDTH) << ' ' << "=================" << '\n';
		std::cout << std::setw(WIDTH) << ' ' << "1. New account" << '\n';
		std::cout << std::setw(WIDTH) << ' ' << "2. Existing account" << '\n';
		std::cout << std::setw(WIDTH) << ' ' << "4. Exit" << '\n';
		//std::cout << spaces << "Test" << std::endl; // <--- An alternative.
		std::cout << std::setw(WIDTH) << ' ' << "Enter choice: ";

		std::cin >> choice;

		if (!std::cin)
		{
			std::cout << "\n"<<std::setw(WIDTH)<< ' ' << "Invalid choice! Please use numbers: ";
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
			std::this_thread::sleep_for(std::chrono::seconds(3));  // Requires header files "chrono" and "thread".
		}
		else if (choice < 1 || choice > 4)
		{
			std::cout << "\n" << std::setw(WIDTH) << ' ' << "Invalid Choice! Numbers are 1 - 4: ";
			std::this_thread::sleep_for(std::chrono::seconds(3));  // Requires header files "chrono" and "thread".
		}
	} while (choice < 1 || choice > 4);

	return choice;
}

I defined "spaces" as a way to show you an alternative to using "std::setw". The part the should look different to you (std::setw(WIDTH) << ' ') defines a block the size of "WIDTH" and prints one space padding the rest of the block with spaces. This work better to position the menu.

By defining "choice" as an "int" this uses the if statement to catch anything that is not a number. I found the the "else if" worked the best for checking the range of the input.

I have found that doing a menu function this way or something similar works the best to get the input and validate it and at the end only return a valid input to use.

The concept may be ahead of where you are, but worth taking the time to understand.

In the N_accounts" function all you need is:
1
2
std::ofstream outfile;
outfile.open("Accounts.txt", std::ios::app);

Notice: since you defined the file stream as an "ofstream" the default in the open statement is for output. You do not need to tell to open for "output", but you do need to tell it to append the file. Otherwise it would clear the contents and then use the defaults of "out" and "app".

Just so you know this can be shortened to just: std::ofstream outfile("Accounts.txt", std::ios::app);. This not only defines the file stream, but opens the file for append. Either way works.

In the if statement you use "std::toupper()". You should also include the header file <cctype>. Do not count on this header file being included for you. I can tell you are using a Windows computer, but I do not know what IDE you are using. The short answer is that not all operating systems, IDEs and compilers are the same. On another system <cctype> may not be included with the header file <iostream>.

Backing up a bit I agree with what zapshe is saying. A struct stored in a vector or an array work much better than reading the file every time you need to. It is quicker to work through the vector than to read the file. And the vector can grow as you need it holding only what you need and having no wasted space as an array does.

I have only worked with the first three functions so far. I will start looking into the rest and see what I can come up with.

Hope that helps,

Andy
Topic archived. No new replies allowed.