Array-Temperature Calculations

I'm sure someone has seen this exact problem before but I never found a solution.. so I built my own version but I'm having some trouble. My output is going crazy and I don't even think it's reading my input correctly.. any help would be greatly appreciated. Basically I'm reading temperatures from a file (2 columns, 12 rows) and generating some functions to calculate certain the averages, highest, lowest (see code). NOTE: First column are highs, second column are lows.

----input---
99 75
84 36
100 68
75 65
91 78
86 69
78 59
58 36
59 46
88 78
99 86
66 45

---output---
Average high for the year: -71582754.00

Average low for the year: -71582754.00

The index high temperature is 86

The index low temperature is 0

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

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

ifstream inData;
ofstream outData;

const int cols = 2;
const int rows = 12;

void getData(int listTemp[rows][cols]);
void averageHigh(int listTemp[rows][cols]);
void averageLow(int listTemp[rows][cols]);
void indexHighTemp(int listTemp[rows][cols]);
void indexLowTemp(int listTemp[rows][cols]);

int main()
{
	int listTemp[rows][cols];

	inData.open("tempsinput.txt");
	if (!inData)
	{
		cout << "No file has been found..." << endl;
		system("pause");
		return 1;
	}

	outData.open("tempsoutput.txt");
	outData << fixed << showpoint;
	outData << setprecision(2);

	getData(listTemp);
	averageHigh(listTemp);
	averageLow(listTemp);
	indexHighTemp(listTemp);
	indexLowTemp(listTemp);

	inData.close();
	outData.close();

	system("pause");
	return 0;
}

void getData(int listTemp[rows][cols])
{
	int r; //for rows
	int c; //for columns

	for (r = 0; r < rows; r++)
	{
		for (c = 0; c < cols; c++)
		{
			inData >> listTemp[c][r] >> listTemp[c][r];
		}
	}
}

void averageHigh(int listTemp[rows][cols])
{
	int highSum = 0;
	double highAverage;	   

	for (int i = 0; i < rows; i++)
	{
		highSum = listTemp[i][0] + highSum;		 
	}
	highAverage = highSum / rows;
	outData << "Average high for the year: " << highAverage << endl << endl;
}

void averageLow(int listTemp[rows][cols])
{
	int lowSum = 0;
	double lowAverage;

	for (int i = 0; i < rows; i++)
	{
		lowSum = listTemp[i][0] + lowSum;
	}
	lowAverage = lowSum / rows;
	outData << "Average low for the year: " << lowAverage << endl << endl;
}

void indexHighTemp(int listTemp[rows][cols])
{
	int highestIndex = 1;

	for (int i = 0; i < rows; i++)
	{
		if (listTemp[0][i] > highestIndex)
			highestIndex = listTemp[0][i];
	}
	outData << "The index high temperature is " << highestIndex << endl << endl;
}

void indexLowTemp(int listTemp[rows][cols])
{
	int lowestIndex = 0;

	for (int i = 0; i < rows; i++)
	{
		if (lowestIndex > listTemp[0][i])
		{
			lowestIndex = listTemp[0][i];
		}
	}
	outData << "The index low temperature is " << lowestIndex << endl << endl;
}
Last edited on
Look closely at this snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
void getData(int listTemp[rows][cols])
{
	int r; //for rows
	int c; //for columns

	for (r = 0; r < rows; r++)
	{
		for (c = 0; c < cols; c++)
		{
			inData >> listTemp[c][r] >> listTemp[c][r];
		}
	}
}


It appears that you may have your rows and columns reversed. Look at how the array is shown in the function signature, and then look at how you're storing the values.

You should also stop using the global variables, make the variables local to a function then pass these variables to and from your functions as required.

On line 70, you used this

highSum = listTemp[i][0] + highSum;

and on line 83, this

lowSum = listTemp[i][0] + lowSum;

but on 96 and 109,

you used correct syntax

i.e highestIndex = listTemp[0][i];

Also, according to me your indexLowTemp and averageLow functions need editing as below resp.

1
2
3
4
5
6
7
8
9
void indexLowTemp(int listTemp[rows][cols]) {
	int lowestIndex = listTemp[1][0];
	for (int i = 0; i < rows; ++i) {
		if (lowestIndex > listTemp[1][i]) {
			lowestIndex = listTemp[1][i];
		}
	}
	outData << "The index low temperature is " << lowestIndex << endl << endl;
}


1
2
3
4
5
6
7
8
9
10
void averageLow(int listTemp[rows][cols]) {
	int lowSum = 0;
	double lowAverage;

	for (int i = 0; i < rows; ++i) {
		lowSum = listTemp[1][i] + lowSum;
	}
	lowAverage = lowSum / rows;
	outData << "Average low for the year: " << lowAverage << endl << endl;
}
Can you explain to me why we increment the lows and highs differently? I get the array setup, but I don't exactly know how (ie:[0][i], etc.) works. And I edited where I thought you guys were trying to correct me but I don't get the correct input.. Here's the updated code.

Edit: my global variables, if it's not good practice or if they shouldn't be there at all, where would I put them instead? I try to keep the code as light as possible but if you think I should move them and pass them by another means please explain to me how I would do that, I am a beginner after all :p

Thank for the replies!

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

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

ifstream inData;
ofstream outData;

const int cols = 2;
const int rows = 12;

void getData(int listTemp[rows][cols]);
void averageHigh(int listTemp[rows][cols]);
void averageLow(int listTemp[rows][cols]);
void indexHighTemp(int listTemp[rows][cols]);
void indexLowTemp(int listTemp[rows][cols]);

int main()
{
	int listTemp[rows][cols];

	inData.open("tempsinput.txt");
	if (!inData)
	{
		cout << "No file has been found..." << endl;
		system("pause");
		return 1;
	}

	outData.open("tempsoutput.txt");
	outData << fixed << showpoint;
	outData << setprecision(2);

	getData(listTemp);
	averageHigh(listTemp);
	averageLow(listTemp);
	indexHighTemp(listTemp);
	indexLowTemp(listTemp);

	inData.close();
	outData.close();

	system("pause");
	return 0;
}

void getData(int listTemp[rows][cols])
{
	int r; //for rows
	int c; //for columns

	for (c = 0; c < cols; c++)
	{
		for (r = 0; r < rows; r++)
		{
			inData >> listTemp[c][r] >> listTemp[c][r];
		}
	}
}

void averageHigh(int listTemp[rows][cols])
{
	int highSum = 0;
	int highAverage;	   

	for (int i = 0; i < rows; i++) //increments through highs
	{
		highSum = listTemp[0][i];		 
	}
	highAverage = highSum / rows;
	outData << "Average high for the year: " << highAverage << endl << endl;
}

void averageLow(int listTemp[rows][cols])
{
	int lowSum = 0;
	int lowAverage;

	for (int i = 0; i < rows; ++i) //increments through lows
	{
		lowSum = listTemp[1][i];
	}
	lowAverage = lowSum / rows;
	outData << "Average low for the year: " << lowAverage << endl << endl;
}

void indexHighTemp(int listTemp[rows][cols])
{
	int highestIndex = 0;

	for (int i = 0; i < rows; i++) //increments to find highest index
	{
		if (listTemp[0][i] > highestIndex)
		{
			highestIndex = listTemp[0][i];
		}
	}
	outData << "The index high temperature is " << highestIndex << endl << endl;
}

void indexLowTemp(int listTemp[rows][cols])
{
	int lowestIndex = listTemp[1][0];

	for (int i = 0; i < rows; ++i) //increments to find lowest index
	{
		if (lowestIndex > listTemp[1][i])
		{
			lowestIndex = listTemp[1][i];
		}
	}
	outData << "The index low temperature is " << lowestIndex << endl << endl;
}
Last edited on
Yes the two global stream variables are a bad practice. Make them local to a function, getData() would probably be correct in this program, then pass them to the functions that require them.

Can you explain to me why we increment the lows and highs differently?

Look at your input file.
99 75
The high temperature is the first entry, the low temperature is the second entry. You could use two different arrays instead of the multidimensional array, it might be less confusing to you.

Part of your problem appears to be in this function:
1
2
3
4
5
6
7
8
9
10
11
12
13
void getData(int listTemp[rows][cols])
{
	int r; //for rows
	int c; //for columns

	for (c = 0; c < cols; c++)
	{
		for (r = 0; r < rows; r++)
		{
			inData >> listTemp[c][r] >> listTemp[c][r];
		}
	}
}


You really shouldn't be using for() loops in this function. One simple while() loop should be adequate.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int getData(int listTemp[rows][cols])
{
        ifstream inData("tempsinput.txt");
        if(!inData)
        {      // The file opening failed, stop processing, return error code.
                return -1;
        {
        int i = 0;
	while(i < rows && inData >> listTemp[0][i] >> listTemp[1][i] )
	{  // Don't forget to make sure you check that the array is in bounds.
		++i;
	}
        // Return the number of lines actually read.
        return i;
}


Note: instead of returning an error code you could throw an exception, if you've studied them. And in this version you don't open the file in main() and you don't need the global variables.


Well the point of this program was to help me understand multidimensional arrays better, so I appreciate the help :) but I was wondering if you could edit the entirety of the program to match the new int getData function you created.

edit: I was trying to avoid passing by value but it definitely doesn't hurt.
Last edited on
but I was wondering if you could edit the entirety of the program to match the new int getData function you created.

It would be better if you gave it a try. I already know how to do it, you need to learn.

edit: I was trying to avoid passing by value but it definitely doesn't hurt.

What?
I was referring to the int function you changed from a void. Voids pass by reference while the int fx passes by value.. right? lol I'm constantly second guessing myself when it comes to this stuff.
The return type has nothing to do with pass by reference or pass by value. Both pass by reference and pass by value have to deal with the parameters not the return value of the function. You can pass variables by value, by reference, or by pointer no matter what you return.

I'm constantly second guessing myself when it comes to this stuff.

Why? Why bother guessing, when there's loads of resources online to help you learn and understand what this stuff actually means and how it works?
How would I go about declaring my inData/outData variables from the getData fx to my main?
What?


What inData and outData variables are you talking about?


The getData() function is only using your array, that is passed as a parameter, from main(), everything else is local to getData().

Right I see, so I'm going to have to output everything within that getData() fx then, too?

ie: outData << "The index low temperature is " << averageHigh(listTemp) << endl << endl;
so I'm going to have to output everything within that getData() fx then, too?

Why?

The getData() function is not outputting anything, it is retrieving information from your file and putting that information in your array.

I'm confused.. I'll paste what I have again and let me know where I'm going off tangent.. Did you completely replace int main() with int getData()? Which is why I'm asking about the inData/outData variables. Since I want to output some information about each function I call, do I only declare ifstream inData; ofstream outData; within a certain function and how do they pass around if I'm declaring them within a function besides main(). See where my confusion is coming from? Sorry if I'm not understanding you correctly..

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

using namespace std;

const int cols = 2;
const int rows = 12;

int getData(int listTemp[rows][cols]);
int averageHigh(int listTemp[rows][cols]);
int averageLow(int listTemp[rows][cols]);
int indexHighTemp(int listTemp[rows][cols]);
int indexLowTemp(int listTemp[rows][cols]);

int main()
{
	int listTemp[rows][cols];

	getData(listTemp);
	averageHigh(listTemp);
	averageLow(listTemp);
	indexHighTemp(listTemp);
	indexLowTemp(listTemp);

	system("pause");
	return 0;
}

int getData(int listTemp[rows][cols])
{
	ifstream inData("tempsinput.txt");
	ofstream outData("tempsoutput.txt");

	if (!inData)
	{
		return -1; //stop processing, error code
		{
			int i = 0;
			while (i < rows && inData >> listTemp[0][i] >> listTemp[1][i])
			{ //array within bounds
				++i;
			}
			  //return the number of lines actually read
			return i;
		}
	}
	outData << "The index low temperature is " << averageHigh(listTemp) << endl << endl;
	outData << "The index low temperature is " << averageLow(listTemp) << endl << endl;
	outData << "The index low temperature is " << indexHighTemp(listTemp) << endl << endl;
	outData << "The index low temperature is " << indexLowTemp(listTemp) << endl << endl;

	inData.close();
	outData.close();
}

int averageHigh(int listTemp[rows][cols])
{
	int highSum = 0;
	int highAverage;	   

	for (int i = 0; i < rows; i++) //increments through highs
	{
		highSum = listTemp[0][i];		 
	}
	highAverage = highSum / rows;
	return highAverage;
}

int averageLow(int listTemp[rows][cols])
{
	int lowSum = 0;
	int lowAverage;

	for (int i = 0; i < rows; ++i) //increments through lows
	{
		lowSum = listTemp[1][i];
	}
	lowAverage = lowSum / rows;
	return lowAverage;
}

int indexHighTemp(int listTemp[rows][cols])
{
	int highestIndex = 0;

	for (int i = 0; i < rows; i++) //increments to find highest index
	{
		if (listTemp[0][i] > highestIndex)
		{
			highestIndex = listTemp[0][i];
		}
	}
	return highestIndex;
}

int indexLowTemp(int listTemp[rows][cols])
{
	int lowestIndex = listTemp[1][0];

	for (int i = 0; i < rows; ++i) //increments to find lowest index
	{
		if (lowestIndex > listTemp[1][i])
		{
			lowestIndex = listTemp[1][i];
		}
	}
	return lowestIndex;
}
You inData() doesn't look like the function I suggested. You need to be much more careful about your brace placement. And in C++ you don't need to call the close function. The class destructor will do this when the class goes out of scope.

Why did you add all that output stuff to an input function? You should strive to have your functions do as little as possible. The getData() function should only be getting the data from the file and filling in the array values.

It would be better if you created another function to do the output.

And in main() you should check save that return value.

1
2
3
	int numElements = getData(listTemp);
        if(numElements < 1) // Check to see that you actually read something from the file.
                return numElements;


Also you should be using that return value in all of the other functions.
1
2
3
4
5
6
7
8
9
10
11
12
int averageHigh(int listTemp[rows][cols], int numberOfElemets);
...
	averageHigh(listTemp, numElements);
...
int averageHigh(int listTemp[rows][cols], int numElements)
{
	int highSum = 0;
	int highAverage;	   

	for (int i = 0; i < numElemets; i++) // notice the change here.
...
	highAverage = highSum / numElemets; // Notice the change here. 
Wouldn't I need brackets around: if (numElements < 1){ return numElements; } ?

And the question I had about the input/output files, I'm using visual studio 2015 and it gives me errors if I only define them within that getData() function. So I was wondering why I wouldnt globalize those and what my alternative would be. I've used fstream plenty before but not within different functions like this.

Also, creating that int numOfElements was a huge help..

edit: int numElements = getData(listTemp);
^
too few arguments
Last edited on
I'm using visual studio 2015 and it gives me errors if I only define them within that getData() function.

What errors?

Show your current code and post your complete error messages, all of them exactly as they appear in your development environment.

So I was wondering why I wouldnt globalize those and what my alternative would be.

Global variables are a very very bad practice. Your alternative is to properly declare the variables in the proper scope.
Wouldn't I need brackets around: if (numElements < 1){ return numElements; } ?

Technically, no, you don't need them, if the conditional block is only a single statement. But I'd recommend using them anyway, because it reduces the risk of introducing errors if you ever want to add more statements to the block.

Topic archived. No new replies allowed.