Calling functions within functions

Hi, I'm having trouble getting results from some calculations posted into a file using <fstream>. I've changed the results to cout so that they'll display in the console but that's just to save a bit of time while troubleshooting.

This is the code of the function which is then being called in main() in another cpp file.

Only result I'm getting is -1.#IND for the gradient, y-int and r.

I'm using functions in this code (m, yint and coe) which I use elsewhere and are working correctly there, just don't seem to work correctly when called here. Can you not call functions inside other functions or what?

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
double writecalculations(int n, double x, double y, double xy, double x2, double y2)
{
	string calcfilenamestring;
	double gradient, yintercept, coefficient = 0.0;

	ofstream outfile;
	cout << "Enter name of file to be written to: ";
	cin >> calcfilenamestring;
	
 	outfile.open(calcfilenamestring.c_str());
	if (outfile.fail())
	{ 
		cout << "ERROR: The file " << calcfilenamestring << " has not successfully opened" << endl; 
		exit(1); 
	}
	
	gradient = m(n, xy, x, y, x2);
	cout << "gradient = " << gradient << endl;

	yintercept = yint(n, xy, x, y, x2);
	cout << "y-intercept = " << yintercept << endl;
			
	coefficient = coe(n, xy, x, y, x2, y2);
	cout << "r = " << coefficient << endl;
	
	outfile.close();
	cout << endl;
	return gradient, yintercept, coefficient;
}


If it helps at all here are the 3 functions being called above^:

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
double m(int n, double xy, double x, double y, double x2)
{
	double sum = 0.0;
	
	sum = (n*xy - x*y) / (n*x2 - x*x);
	
	return sum;
}

double yint(int n, double xy, double x, double y, double x2)
{
	double sum = 0.0;
	
	sum = (x2*y - x*xy) / (n*x2 - x*x);
	
	return sum;
}

double coe(int n, double xy, double x, double y, double x2, double y2)
{
	double sum = 0.0;
	
	sum = (n*xy - x*y) / sqrt((n*x2 - x*x) * (n*y2 - y*y));
	
	return sum;
}



In the main() I have it being read from the following case statement:

1
2
3
4
5
case 'c':
	cout << "Write calculations to file" << endl;
			
	writecalculations(SIZE1, sumX, sumY, sumXY, sumX2, sumY2);
	break;


The values sumX, sumY, etc. are all results from separate functions which I've tested and know are working correctly.

Hopefully this makes sense, it's a bit convoluted and rather hard to explain it well. Any help regarding the problem would be appreciated!
Can you not call functions inside other functions or what?

Absolutely you can call functions from inside other functions.

A couple of comments on your code:

Lines 10-26: You open outfile, but never write to it.

Line 28: You can't return three values in a return statement. This is not what the comma operator does.
http://www.cplusplus.com/doc/tutorial/operators/
This

return gradient, yintercept, coefficient;

will return coefficient only. gradient, yintercept are ignored

If you want to return three values you need a struct
Ok, thanks for the reply. In response:

Lines 10-26: You open outfile, but never write to it.


Yea, where the cout's are currently I will change them into outfile's once I get the actual function itself working correctly, it's just a little bit faster to have them show up in the console than whatever file I write them to if I'm checking for errors.

Line 28: You can't return three values in a return statement. This is not what the comma operator does.
http://www.cplusplus.com/doc/tutorial/operators/


Alrighty, thanks, definitely good to know!

I had the whole thing as a void before, just forgot to change it back as I was messing around with things to try and get it to work.

Here is what it was previously

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
void writecalculations(int n, double x, double y, double xy, double x2, double y2)
{
	string calcfilenamestring;
	double gradient, yintercept, coefficient;

	ofstream outfile;
	cout << "Enter name of file to be written to: ";
	cin >> calcfilenamestring;
	
 	outfile.open(calcfilenamestring.c_str());
	if (outfile.fail())
	{ 
		cout << "ERROR: The file " << calcfilenamestring << " has not successfully opened" << endl; 
		exit(1); 
	}
	
	gradient = m(n, xy, x, y, x2);
	cout << "gradient = " << gradient << endl;

	yintercept = yint(n, xy, x, y, x2);
	cout << "y-intercept = " << yintercept << endl;
			
	coefficient = coe(n, xy, x, y, x2, y2);
	cout << "r = " << coefficient << endl;
	
	outfile.close();
	cout << endl;
}
Your function looks fine. However, I would be careful in m, yint and coe to ensure that the divisors are non-zero.
Your function looks fine. However, I would be careful in m, yint and coe to ensure that the divisors are non-zero.


Well I've already calculated them in another part of the case statement in main() and they work perfectly, giving me the correct values and everything. For that case statement I have the following code:

1
2
3
4
5
6
7
8
9
	gradient = m(SIZE1, sumXY, sumX, sumY, sumX2);
	cout << "Gradient 'm': " << gradient << endl;

	yintercept = yint(SIZE1, sumXY, sumX, sumY, sumX2);
	cout << "Y-intercept 'c': " << yintercept << endl;
	cout << "y = " << gradient << "x + " << yintercept << endl;
			
	coefficient = coe(SIZE1, sumXY, sumX, sumY, sumX2, sumY2);
	cout << "Correlation coefficient 'r': " << coefficient << endl;


I get the correct results calling the functions here, it's only when I try to call them again so I can print them to a file that I get a bad result.

I'm just not sure what's differing between when I call the functions in the case statement and when I call them in the other function that gives me the bad results.


EDIT: Okay, I just tried it again with the function set to void and the cout's replaced with outfiles and it seems to be working now not exactly sure what's changed since I've been struggling over this for the last few hours but it's fixed in any case.

Thanks for the help everyone!
Last edited on
Can you post main please?
Sure. Just to anyone wondering, I did some further testing and it was happening because I needed to go through another case to get values for the other functions before writing them to file. I added the other functions to the case I was having trouble with and it works perfectly everytime now, even if I haven't used the other case statement first.

Here's the main as it currently stands:

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
#include "sort.h" //quicksort functions
#include "arrayio.h" //fill functions
#include "linreg.h"
#include "fileio.h"
#include <iostream>
#include <fstream>
using namespace std;

//add function prototypes in separate header files 

int main()
{
	const int SIZE1 = 10;
	double xarray[SIZE1] = {0};
	double yarray[SIZE1] = {0};
	double sumX = 0.0;
	double sumY = 0.0;
	double sumXY = 0.0;
	double sumX2 = 0.0;
	double sumY2 = 0.0;
	double gradient = 0.0;
	double yintercept = 0.0;
	double coefficient = 0.0;

	char command = '\0';

	do
	{
		cout << "STATPACK 3.0\tStatistics Program\n------------\t------------------\n";
		cout << "Commands:\nf - fill arrays\nd - display arrays\ns - sort each array separately\nx - sort both arrays by x (preserves (x,y) coordinates)\n";
		cout << "l - linear regression\nr - read x, y arrays from file\nw - write x, y arrays to file\nc - write calculations to file\n";
		cout << "q - quit\n";
		cin >> command;

		switch (tolower(command))
		{
		case 'f':
			//fill array with random data
			cout << "Fill array " << endl << endl;
			fillarray(SIZE1, xarray);
			fillarray(SIZE1, yarray);
			break;

		case 'd':
			cout << "Display array " << endl << endl;
			cout << "    x:" << endl;
			showarray(SIZE1, xarray);
			cout << "    y:" << endl;
			showarray(SIZE1, yarray);
			break;

		case 's':
			cout << "Sort arrays " << endl << endl;
			quickSort(xarray, 0, SIZE1-1);
			quickSort(yarray, 0, SIZE1-1);
			break;

		case 'x':
			cout << "Sort arrays by x " << endl << endl;
			quickSortx(xarray, yarray, 0, SIZE1-1);
			break;
		
		case 'l':
			sumX = sumofX(SIZE1, xarray);
			cout << "Sum of x: " << sumX << endl;

			sumY = sumofY(SIZE1, yarray);
			cout << "Sum of y: " << sumY << endl;

			sumXY = sumofXY(SIZE1, xarray, yarray);
			cout << "Sum of xy: " << sumXY << endl;

			sumX2 = sumofsquaresX(SIZE1, xarray, xarray);
			cout << "Sum of squares(x): " << sumX2 << endl;

			sumY2 = sumofsquaresY(SIZE1, yarray, yarray);
			cout << "Sum of squares(y): " << sumY2 << endl;

			gradient = m(SIZE1, sumXY, sumX, sumY, sumX2);
			cout << "Gradient 'm': " << gradient << endl;

			yintercept = yint(SIZE1, sumXY, sumX, sumY, sumX2);
			cout << "Y-intercept 'c': " << yintercept << endl;
			cout << "y = " << gradient << "x + " << yintercept << endl;
			
			coefficient = coe(SIZE1, sumXY, sumX, sumY, sumX2, sumY2);
			cout << "Correlation coefficient 'r': " << coefficient << endl;

			cout << endl;
			break;

		case 'r':
			cout << "Read x, y arrays from file" << endl << endl;
			readarray(SIZE1, xarray, yarray);
			break;

		case 'w':
			cout << "Write x, y arrays to file" << endl << endl;
			writearray(SIZE1, xarray, yarray);
			break;
		
		case 'c':
			/* calculations regarding sum of x, sum of squares of x, etc. included in this case statement
			so that calculations can be posted to file immediately without having to go through 'l' case first */
			sumX = sumofX(SIZE1, xarray);			
			sumY = sumofY(SIZE1, yarray);			
			sumXY = sumofXY(SIZE1, xarray, yarray);
			sumX2 = sumofsquaresX(SIZE1, xarray, xarray);
			sumY2 = sumofsquaresY(SIZE1, yarray, yarray);
			gradient = m(SIZE1, sumXY, sumX, sumY, sumX2);
			yintercept = yint(SIZE1, sumXY, sumX, sumY, sumX2);
			coefficient = coe(SIZE1, sumXY, sumX, sumY, sumX2, sumY2);			
			
			cout << "Write calculations to file" << endl;
			writecalculations(SIZE1, sumX, sumY, sumXY, sumX2, sumY2);
			break;

		case 'q':
			cout << "exiting...";
			break;
		
		default:
			cout << "Valid commands are s, f, q\n";
		}

	}while (toupper(command) != 'Q');

	cout << "Bye... " << endl;
	return 0;
}

Topic archived. No new replies allowed.