Function calls not carrying variable values?

I know my code is a hell of a TL;DR, but at this point I am desperate. This program is about the extent of C++ experience (and the extent of my ability to understand anything I've googled about this), and despite almost two weeks of trying to figure this out, I can't for the life of me figure out why it is outputting zeros across the board.

The program is supposed to take an input file, presumably some kind of .txt file, and output a chart for tax information. I did this exact program seamlessly without the function calls---and it works with global variable definitions (but I'm not allowed to define variables globally). Every function return value ends up as zero no matter how many tweaks and tests I do.
Last edited on
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
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

float exemptionfunc(ifstream& files, string errormessageM, char marital, int children, int errordataM, float pension, float exemptions);
float taxincomefunc(ifstream& files, float income, float pension, float deductions, float taxincome, float exemptions);
float taxowedfunc(ifstream& files, string errormessageP, int errordataP, float taxincome, float pension, float taxowed);
int openfiles(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, int errorcheck);
void closefiles(ifstream& files, ofstream& outfile, ofstream& errorfile);
void readdata(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);
void outputdata(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);
void errorout(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);

int main() {
	ifstream files;
	ofstream outfile, errorfile;
	string 	filename, lastname, errormessageM, errormessageP;
	char marital;
	int children, errorcheck, errordataM, errordataP;
	float income, pension, deductions, taxincome, taxowed, exemptions;
	
	errormessageM = "Invalid Marital Status.";
	errormessageP = "Invalid Pension Percentage.";
	errordataM = 0;
	errordataP = 0;
	
	openfiles(files, outfile, errorfile, filename, errorcheck);
	if (errorcheck=1) {
		readdata(files, outfile, errorfile, filename, lastname, errormessageM, errormessageP, marital, children,  
			errordataM, errordataP, income, pension, deductions, taxincome, taxowed, exemptions);
		closefiles(files, outfile, errorfile);
		return 0;
	}	
	else {
		cout << "Closing program.\n";
		return 0;
	}			
}
//***
float exemptionfunc(ifstream& files, string errormessageM, char marital, int children, int errordataM, float pension, 
	float exemptions) {
	switch (marital) {
		case 'M': {
				errordataM = 0;
				errormessageM = " ";
				exemptions = 6000 + (700 * 2) + (700 * children);
				break;
		}
		case 'S': {
				errordataM = 0;
				errormessageM = " ";
				exemptions = 3000 + (700) + (700 * children);
				break;
		}
		default: {
				errordataM = 1;
				errormessageM = "Invalid Marital Status.";
				exemptions = 3000 + (700) + (700 * children);
				break;
		}
	}
	return exemptions;
}
//***
float taxincomefunc(ifstream& files, float income, float pension, float deductions, float exemptions, float taxincome) {
	deductions = pension * income;
	taxincome = (income - exemptions) - deductions;
	return taxincome;
}
//***
float taxowedfunc(ifstream& files, string errormessageP, int errordataP, float taxincome, float pension, float taxowed) {
	if (pension >= .06) {		
		errormessageP = "Invalid Pension Percentage.";
		errordataP = 1;
	}
	if (pension <= .05) {
		errormessageP = " ";
		errordataP = 0;
	}
	if (taxincome <= 20000.00) {
		taxowed = (0.15 * taxincome);
	}
	if (taxincome >= 20000.01 && taxincome <= 50000.00) {
		taxowed = (0.25 * taxincome) + 2250;
	}
	if (taxincome >= 50000.01) {
		taxowed = (0.35 * taxincome) + 8460;
	}
	return taxowed;
}
//***
int openfiles(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, int errorcheck) {
	cout << "Please tell me your file name.\n";
	cin >> filename;
	files.open(filename.c_str());
	outfile.open("Outputfile.txt"); 
	errorfile.open("Errorfile.txt");
	if (files.is_open()) {
		errorcheck=1;
	}
	else {
		cout << "Could not open file.  Please exit program.\n";
		errorcheck=0;
	}
	return errorcheck;
}
//***
void closefiles(ifstream& files, ofstream& outfile, ofstream& errorfile) {
	files.close();
	outfile.close();
	errorfile.close();
}
//***
void readdata(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions) {
			if (files.is_open()) {		
			cout	<< "========================================================================\n";
			cout	<< setw(9) << left << "Name " << setw(9) << left << "Gross-Income "
					<< setw(9) << left << "Exemptions " << setw(9) << left << "Pension "
					<< setw(9) << left << "Taxable-Income " << setw(10) << left << "Tax-Owed: " << "\n";
			cout	<< "========================================================================\n";						
			outfile	<< "========================================================================\n";
			outfile	<< setw(9) << left << "Name " << setw(9) << left << "Gross-Income "
					<< setw(9) << left << "Exemptions " << setw(9) << left << "Pension "
					<< setw(9) << left << "Taxable-Income " << setw(10) << left << "Tax-Owed: " << "\n";
			outfile	<< "========================================================================\n";					
				do {
					files >> lastname >> marital >> children >> income >> pension;
					exemptionfunc(files, errormessageM, marital, children, errordataM, pension, exemptions);
					taxincomefunc(files, income, pension, deductions, taxincome, exemptions);
					taxowedfunc(files, errormessageP, errordataP, taxincome, pension, taxowed);
					outputdata(files, outfile, errorfile, filename, lastname, errormessageM, errormessageP, marital, children, 
						errordataM, errordataP, income, pension, deductions, taxincome, taxowed, exemptions);
				} 	while (files);	
			}	
			if (outfile.is_open()) {
				cout << "======================================================================\n";
				cout << "Saved output file successfully.  You can find it as 'Outputfile.txt' at your convenience.\n";
			}	
			else {
				cout << "Could not save output file.\n";
			}
			if (errorfile.is_open()) {
				cout << "Errors were successfully logged.  You can find them in 'Errorfile.txt' at your convenience.\n";
			}
			else {
				cout << "Could not save error log.\n";
			}
}
//***
void outputdata(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions) {		
		if (files) {	
			if (errordataM == 0 && errordataP == 0) {
				cout 	<< fixed << showpoint << setprecision(2);
				cout 	<< setw(7)  << left << lastname << "  "   
						<< setw(11) << left << income << "  "
						<< setw(9)  << left << exemptions << "  "
						<< setw(5)  << left << pension * 100 << setw(4) << left << "% "
						<< setw(13) << left << taxincome << "  "
						<< setw(8)  << left << taxowed << "  " << "\n";
				outfile	<< fixed << showpoint << setprecision(2);
				outfile << setw(7)  << left << lastname << "  "   
						<< setw(11) << left << income << "  "
						<< setw(9)  << left << exemptions << "  "
						<< setw(5)  << left << pension * 100 << setw(4) << left << "% "
						<< setw(13) << left << taxincome << "  "
						<< setw(8)  << left << taxowed << "  " << "\n";
			}						
			else {	
				errorout(files, outfile, errorfile, filename, lastname, errormessageM, errormessageP, marital,
					children, errordataM, errordataP, income, pension, deductions, taxincome, taxowed, exemptions);
			}
		}		
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void errorout(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions) {
	
	errorfile	<< fixed << showpoint << setprecision(2);
	errorfile	<< setw(6) << left << lastname << "  "   
				<< setw(8) << left << income << "  "
				<< setw(6) << left << exemptions << "  "
				<< setw(3) << left << pension * 100 << setw(4) << left << "% "
				<< setw(9) << left << taxincome << "  "
				<< setw(7) << left << taxowed << "  " 
				<< setw(23)<< left << errormessageM
				<< setw(23)<< left << errormessageP << "\n";
}
//*** 
1
2
3
4
5
6
7
8
9
void readdata(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);
void outputdata(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);
void errorout(ifstream& files, ofstream& outfile, ofstream& errorfile, string filename, string lastname, string errormessageM,
	string errormessageP, char marital, int children, int errordataM, int errordataP, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);


What the hell? Now I understand why your code is so Tl;dr haha

You should find a way to wrap these parameters into a wrapper (struct, class) etc in order to shorten your functions. Using it makes your life easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct tax_struct
{
string filename;
string lastname;
string errormessageM;
string errormessageP;
char marital;
int children, errordataM, errordataP;
float income, pension, deductions, taxincome, taxowed, exemptions;
};


void readdata(ifstream& files, ofstream& outfile, ofstream& errorfile, tax_struct mydata);
void outputdata(ifstream& files, ofstream& outfile, ofstream& errorfile, tax_struct mydata);
void errorout(ifstream& files, ofstream& outfile, ofstream& errorfile, tax_struct mydata); 
Also IMO several of your functions are doing too much. For example the readdata() file should just be reading the file, all of those print statements should be elsewhere, and you may want to consider using a vector or array of a class/structure that holds the records.

And note that just checking if the files are open() doesn't insure that the streams are not in an error state.
Alot of these details I'm actually fully aware of (the fact that structures would simplify the code visually, and the fact that my readdata function is cout'ing a message, etc) but due to extremely pressing time constraints I am trying to focus on why my function data is not transferring instead (because the last two weeks will have been for naught if I can't figure this out).
At least, copy and show us your program output, but stop where you think the output will go wrong. If possible, please give us a hint.

Also, your test data file that you are working on would be nice too.
You should also post a sample of your input files as well.

And remember when you pass variables by value into a function any changes to that variable in the function is lost when the function returns.

output file should look like
1
2
3
4
5
6
7
8
========================================================================
Name     Gross-Income Exemptions Pension  Taxable-Income Tax-Owed: 
========================================================================
Smith    35000.00     3700.00    2.00 %   30600.00       9900.00   
Jones    60000.00     8800.00    5.00 %   48200.00       14300.00  
Harvey   100000.00    7400.00    4.00 %   88600.00       39470.00  
Groober  75000.00     4400.00    0.00 %   70600.00       33170.00  
Chacha   150000.00    8100.00    3.00 %   137400.00      56550.00  


with a separate error file
1
2
Potter  55000.00  4400.00  3.00%   48950.00   14487.50  Invalid Marital Status.                       
Deluca  70000.00  4400.00  50.00%   30600.00   9900.00                         Invalid Pension Percentage.


but turns out as:
1
2
3
4
5
6
7
8
9
10
========================================================================
Name     Gross-Income Exemptions Pension  Taxable-Income Tax-Owed: 
========================================================================
Smith    35000.00     nan        2.00 %   0.00           0.00      
Jones    60000.00     nan        5.00 %   0.00           0.00      
Harvey   100000.00    nan        4.00 %   0.00           0.00      
Potter   55000.00     nan        3.00 %   0.00           0.00      
Groober  75000.00     nan        0.00 %   0.00           0.00      
Chacha   150000.00    nan        3.00 %   0.00           0.00      
Deluca   70000.00     nan        50.00%   0.00           0.00   


with a completely blank error file every time instead. I've tried putting my calculation functions in main() rather than called by readdata(). I've tried quite alot of stuff (like I said, I've been working on this one little problem for almost two weeks now). Somehow, (at least I'm pretty sure) my function return values are being lost in the call and I've never seen this happen before.

The input file we're given is
1
2
3
4
5
6
7
Smith S 0 35000.00 .02
Jones M 2 60000.00 .05
Harvey M 0 100000.00 .04
Potter Q 1 55000.00 .03
Groober S 1 75000.00 .0
Chacha M 1 150000.00 .03
Deluca S 1 70000.00 .50
Last edited on
Ok, let's break down.
Smith S 0 35000.00 .02

What variables do you think you will assign each member of the entry to :

Smith
S
0
35000.00
.02

Also, let us see your function main() again. It will help us debug your code much easier.
within my readdata() function I have the following do-while loop

1
2
3
4
5
6
7
8
do {
					files >> lastname >> marital >> children >> income >> pension;
					exemptionfunc(files, errormessageM, marital, children, errordataM, pension, exemptions);
					taxincomefunc(files, income, pension, deductions, taxincome, exemptions);
					taxowedfunc(files, errormessageP, errordataP, taxincome, pension, taxowed);
					outputdata(files, outfile, errorfile, filename, lastname, errormessageM, errormessageP, marital, children, 
						errordataM, errordataP, income, pension, deductions, taxincome, taxowed, exemptions);
				} 	while (files);	


establishing variables from the input file and then processing those variables through the three calculation functions I am using, and then being output via outputdata(). When I copy those calculations into this exact loop, it works wonderfully. It's only when I split it into separate functions and call those functions from the loop that it falls apart.

my function main()
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
int main() {
	ifstream files;
	ofstream outfile, errorfile;
	string 	filename, lastname, errormessageM, errormessageP;
	char marital;
	int children, errorcheck, errordataM, errordataP;
	float income, pension, deductions, taxincome, taxowed, exemptions;
	
	errormessageM = "Invalid Marital Status.";
	errormessageP = "Invalid Pension Percentage.";
	errordataM = 0;
	errordataP = 0;
	
	openfiles(files, outfile, errorfile, filename, errorcheck);
	if (errorcheck=1) {
		readdata(files, outfile, errorfile, filename, lastname, errormessageM, errormessageP, marital, children,  
			errordataM, errordataP, income, pension, deductions, taxincome, taxowed, exemptions);
		closefiles(files, outfile, errorfile);
		return 0;
	}	
	else {
		cout << "Closing program.\n";
		return 0;
	}			
}

defining variables. calling openfiles(), using the return value from a successful open to open readdata(). readdata() is the big function---using the aforementioned loop to define variable values and then call other functions to calculate totals and output those totals---lastly followed by a closefile() function that closes the files.
Last edited on
Let's look at the exemptionfunc() signature:
1
2
float exemptionfunc(ifstream& files, string errormessageM, char marital, int children, int errordataM, float pension, 
	float exemptions) {

Look how you're passing all the variables (except files). You are passing by value. That means that any changes exemptionfunc() makes to those variables are lost when that function returns to the calling function. You need to pass any parameter you want to change by reference (the way you did files) if you want to see any changes in those variables.

Last edited on
embarrassing confession time: the difference between variable& and variable was something I'd been trying to figure out for months, but because I lacked the keyword(s) needed to refer to this question in order to do an effective search I'd always just kind of moved on without that knowledge.

So if I understand you correctly
1
2
3
4
5
6
7
8
int number;
number = 5;

int returnfunc_one(int number) {
}

int returnfunc_two(int& number) {
}


for returnfunc_one, I am bringing in a constant "5" and, no matter what happens within that function, will output a "5"? If I want to change the value, I need to use returnfunc_two?

I'm assuming I'm oversimplifying things a bit, and I definitely need to do more research on this, but for the purposes of what I am doing hereā€”am I more or less right?
for returnfunc_one, I am bringing in a constant "5"

No, not a constant a copy.

Since this is pass by value, the compiler makes a copy of the variable to pass to the function. So in the function when you use that parameter you are working with the copy, you can modify this variable inside the function and those modifications can be used within that function. However when the function returns to the calling function the copy is destroyed.

For example:
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
#include <iostream>

using namespace std;

int returnFunc_one(int number)
{
   cout << "Number in function before any changes. " << number << endl;
   
   number = number + 10;

   cout << "Number in function after adding 10 to the original value: " << number << endl;

   return (number + 10);
}

int main()
{
   int number = 5;

   cout << "Value of number in main() before function: " << number << endl;

   int number2 = returnfunc_one(number);

   cout << "Value of number in main() after function: " << number << endl;

   cout << "Value of number2 in main() after function: " << number2 << endl;

    return(0);
}


no matter what happens within that function, will output a "5"?

Only to the world outside of returnfunc_one(). Inside the function you can change the value of that variable and use it in other calculations.

As you should be able to see the variable used in the parameter remains the same in main(). However the value returned from the function is different.

If I want to change the value, I need to use returnfunc_two?

You can also use the value returned from the function to alter the value in main():

number = returnfunc_one(number);

When passing by reference, you pass the actual variable to the function so any changes made to the variable in the function are directly reflected in the variable in the calling function. Pass by reference is a way of allowing a function to modify multiple variables in the function, which is useful since you can only return one value using the return statement.

Also for future reference, you should strive to keep the number of parameters reasonable. The definition of "reasonable", while different with different people, is usually fewer than 4 or 5 parameters. With one or two being the norm. Your functions should be defined to do as little as possible, usually doing one thing well and try to keep the IO separate from the logic as much as possible.



Last edited on
Line 18: You have a function prototype for errorout, but no implementation for the function. This is going to cause a linker error.

Line 26-28: All your variables are uninitialized. Because you're passing by value, they are NOT modified by the called functions.

Line 35: errorcheck (which is uninitialized) is passed by value. openfiles receives and changes a copy of the variable. Upon return errorcheck at line 27 is still uninitialized (garbage).

Line 36: You're using the assignment operator (=), not the comparison operator (==). This condition will always be true. You're assigning 1 to errorcheck, then testing the result.

A better idiom is to make openfiles a bool function.
35
36
37
38
bool openfiles (ifstream& files, ofstream& outfile, ofstream& errorfile, string filename);  // removed errorcheck
...
  if (! openfiles(files, outfile, errorfile, filename))  
    return 1;  // openfiles failed, exit program 


Line 48: errordataM, errormessageM and exemptions are passed by value. Any changes made inside this function will not be reflected in the caller's variables. Use pass by reference or use the return value. Note: exemptions is returned, but the returned value is ignored.

Line 73: deductions and taxincome are passed by value. Any changes made inside this function will not be reflected in the caller's variables. Use pass by reference or use the return value. Note: taxincome is returned, but the returned value is ignored.

Line 79: errormessageP, errordataP, taxowed are passed by value. Any changes made inside this function will not be reflected in the caller's variables. Use pass by reference or use the return value. Note: taxowed is returned, but the returned value is ignored.

Line 106: You only check that the input file open succeeded. You should check that the open of the output files were also opened.

Line 125,145,152: If openfiles() succeeded, then there is no need to check is_open() here.

Lines 136-143: Your do loop has problems.
Line 137: If the read fails, you continue as if it was successful resulting in processing a garbage record. You should use a while loop as follows:
1
2
3
  while (files >> lastname >> marital >> children >> income >> pension) 
  {  // Good record read 
  }


Edit: There is no reason to pass the input file (files) to exemptionfunc, taxincomefunc, or taxowedfunc.

There is no reason for errordataM and errordataP. You can check if the an error message has been stored by checking the size of the message string.
1
2
3
  if (errormessageM.size())
  {  // A marital status error message has been stored
  }

Last edited on
Also, let us know if the data your program retrieves from the input file is correct.

1
2
3
4
5
6
7
8
9
while (files >> lastname >> marital >> children >> income >> pension)
{
cin.precision(2);
cout << lastname << ' ';
cout << marital << ' ';
cout << children << ' ';
cout << income << ' ';
cout << pension << ' ' << endl;
}



And let us know if the output is exactly the same as :
Smith S 0 35000.00 0.02
Jones M 2 60000.00 0.05
Harvey M 0 100000.00 0.04
Potter Q 1 55000.00 0.03
Groober S 1 75000.00 0.0
Chacha M 1 150000.00 0.03
Deluca S 1 70000.00 0.50


Edit : It is very very important!! We at the very least need to know if your program is reading a file correctly.
Last edited on
This is not a full cleanup of your program, but it should be enough to get you started.

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
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

float exemptionfunc (string & errormessageM, char marital, int children, float pension);
float taxincomefunc (float income, float pension, float & deductions, float exemptions);
float taxowedfunc (string & errormessageP, float taxincome, float pension);
bool openfiles (ifstream& files, ofstream& outfile, ofstream& errorfile);
void closefiles (ifstream& files, ofstream& outfile, ofstream& errorfile);
void readdata (ifstream& files, ofstream& outfile, ofstream& errorfile, string & lastname, string & errormessageM,
	string & errormessageP, char & marital, int & children, float & income, 
	float & pension, float & deductions, float & taxincome, float & taxowed, float & exemptions);
void outputdata (ofstream& outfile, ofstream& errorfile, const string lastname, const string errormessageM,
	const string errormessageP, char marital, int children, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);
void errorout (ofstream& outfile, ofstream& errorfile, string lastname, string errormessageM,
	string errormessageP, char marital, int children, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions);

int main() 
{   ifstream files;
	ofstream outfile, errorfile;
	string 	lastname, errormessageM, errormessageP;
	char marital;
	int children;
	float income, pension, deductions, taxincome, taxowed, exemptions;
	
	errormessageM = "Invalid Marital Status.";
	errormessageP = "Invalid Pension Percentage.";
			
	if (! openfiles(files, outfile, errorfile))
	    return 1;
	readdata (files, outfile, errorfile, lastname, errormessageM, errormessageP, marital, children,  
			  income, pension, deductions, taxincome, taxowed, exemptions);
	closefiles(files, outfile, errorfile);
	system ("pause");
}
//***
float exemptionfunc (string & errormessageM, char marital, int children, float pension)
{   float exemptions;

    switch (marital) {
		case 'M': {
				errormessageM = "";
				exemptions = 6000.0f + (700 * 2) + (700 * children);
				break;
		}
		case 'S': {
				errormessageM = "";
				exemptions = 3000.0f + (700) + (700 * children);
				break;
		}
		default: {
				errormessageM = "Invalid Marital Status.";
				exemptions = 3000.0f + (700) + (700 * children);
				break;
		}
	}
	return exemptions;
}
//***
float taxincomefunc (float income, float pension, float & deductions, float exemptions) 
{   float taxincome;

	deductions = pension * income;
	taxincome = (income - exemptions) - deductions;
	return taxincome;
}
//***
float taxowedfunc (string & errormessageP, float taxincome, float pension) 
{   float taxowed = 0;

	if (pension >= .06) {		
		errormessageP = "Invalid Pension Percentage.";		
	}
	if (pension <= .05) {
		errormessageP = "";		
	}
	if (taxincome <= 20000.00) {
		taxowed = (0.15f * taxincome);
	}
	if (taxincome >= 20000.01 && taxincome <= 50000.00) {
		taxowed = (0.25f * taxincome) + 2250;
	}
	if (taxincome >= 50000.01) {
		taxowed = (0.35f * taxincome) + 8460;
	}
	return taxowed;
}
//***
bool openfiles(ifstream& files, ofstream& outfile, ofstream& errorfile) 
{   string  filename;

    cout << "Please tell me your file name.\n";
	cin >> filename;
	files.open(filename.c_str());
	if (! files.is_open ())
	{   cout << "Failed to open input file" << endl;
	    return false;
	}
	outfile.open("Outputfile.txt"); 
	if (! outfile.is_open ())
	{   cout << "Failed to open output file" << endl;
	    return false;
	}
	errorfile.open("Errorfile.txt");
	if (! errorfile.is_open ())
	{   cout << "Failed to open error file" << endl;
	    return false;
	}
	return true;    //  All files opened successfully
}

//***
void closefiles(ifstream& files, ofstream& outfile, ofstream& errorfile) 
{   files.close();
	outfile.close();
	errorfile.close();
}

//***
void readdata (ifstream& files, ofstream& outfile, ofstream& errorfile, string & lastname, string & errormessageM,
	string & errormessageP, char & marital, int & children, float & income, 
	float & pension, float & deductions, float & taxincome, float & taxowed, float & exemptions) 
{   cout	<< "========================================================================\n";
	cout	<< setw(9) << left << "Name " << setw(9) << left << "Gross-Income "
			<< setw(9) << left << "Exemptions " << setw(9) << left << "Pension "
			<< setw(9) << left << "Taxable-Income " << setw(10) << left << "Tax-Owed: " << "\n";
	cout	<< "========================================================================\n";						
	outfile	<< "========================================================================\n";
	outfile	<< setw(9) << left << "Name " << setw(9) << left << "Gross-Income "
			<< setw(9) << left << "Exemptions " << setw(9) << left << "Pension "
			<< setw(9) << left << "Taxable-Income " << setw(10) << left << "Tax-Owed: " << "\n";
	outfile	<< "========================================================================\n";					
	while (files >> lastname >> marital >> children >> income >> pension)
	{   exemptions = exemptionfunc (errormessageM, marital, children, pension);
		taxincome = taxincomefunc(income, pension, deductions, exemptions);
		taxowed = taxowedfunc (errormessageP, taxincome, pension);
		outputdata (outfile, errorfile, lastname, errormessageM, errormessageP, marital, children, 
					income, pension, deductions, taxincome, taxowed, exemptions);
	}	
	
	if (outfile) 
	{   cout << "======================================================================\n";
		cout << "Saved output file successfully.  You can find it as 'Outputfile.txt' at your convenience.\n";
	}	
    else
    	cout << "Could not save output file.\n";
	
	if (errorfile)
	{   cout << "Errors were successfully logged.  You can find them in 'Errorfile.txt' at your convenience.\n";
	}
	else 
	{   cout << "Could not save error log.\n";
    }
}

//***
void outputdata (ofstream& outfile, ofstream& errorfile, const string lastname, const string errormessageM,
	const string errormessageP, char marital, int children, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions) 
{   if (errormessageM.size() == 0 && errormessageP.size() == 0) 
    {   cout 	<< fixed << showpoint << setprecision(2);
		cout 	<< setw(7)  << left << lastname << "  "   
				<< setw(11) << left << income << "  "
				<< setw(9)  << left << exemptions << "  "
				<< setw(5)  << left << pension * 100 << setw(4) << left << "% "
				<< setw(13) << left << taxincome << "  "
				<< setw(8)  << left << taxowed << "  " << "\n";
		outfile	<< fixed << showpoint << setprecision(2);
		outfile << setw(7)  << left << lastname << "  "   
				<< setw(11) << left << income << "  "
				<< setw(9)  << left << exemptions << "  "
				<< setw(5)  << left << pension * 100 << setw(4) << left << "% "
				<< setw(13) << left << taxincome << "  "
				<< setw(8)  << left << taxowed << "  " << "\n";
	}						
	else 
	{   errorout (outfile, errorfile, lastname, errormessageM, errormessageP, marital,
				  children, income, pension, deductions, taxincome, taxowed, exemptions);
	}			
}

void errorout (ofstream& outfile, ofstream& errorfile, string lastname, string errormessageM,
	string errormessageP, char marital, int children, float income, 
	float pension, float deductions, float taxincome, float taxowed, float exemptions)
{   //  To be completed */
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Please tell me your file name.
temp1.txt
========================================================================
Name     Gross-Income Exemptions Pension  Taxable-Income Tax-Owed:
========================================================================
Smith    35000.00     3700.00    2.00 %   30600.00       9900.00
Jones    60000.00     8800.00    5.00 %   48200.00       14300.00
Harvey   100000.00    7400.00    4.00 %   88600.00       39470.00
Groober  75000.00     4400.00    0.00 %   70600.00       33170.00
Chacha   150000.00    8100.00    3.00 %   137400.00      56550.00
======================================================================
Saved output file successfully.  You can find it as 'Outputfile.txt' at your con
venience.
Errors were successfully logged.  You can find them in 'Errorfile.txt' at your c
onvenience.
Press any key to continue . . .

Topic archived. No new replies allowed.