Array of Structs assignment help

Hai all,
Got brainfreeze here.
The assignment is to make a program that uses a struct and an array of structs to store the 12 months, and the high
temperature and low temperature for each month. The program should read the Months’ names, and
the temperatures from a given input file called temps.txt. The program should output the highest and
lowest temperatures for the year, and the months that correspond to those temperatures. Your
program MUST use the following functions:
1. Create a struct called Temperature with data members to store month, high temperature and
low temperature.
2. Function loadData: The function reads and stores data in the array of struct from a text file
(temps.txt). void loadData(ifstream &infile, Temperature [], int &size);
3. Function averageHigh: This function calculates and returns that record that has the high
temperature. From that, you can print the high temperature and the corresponding month in
main. Temperaure averageHigh(Temperature [], int size);
4. Function averageLow: This function calculates and returns that record that has the low
temperature. From that, you can print the low temperature and the corresponding month in
main. Temperaure averageLow(Temperature [], int size);


I am completely lost as of yet and in dire need of help
Any hints?

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

using namespace std;

//struct data type - Temperature
struct Temperature
{
	string month;
	int highTemp;
	int lowTemp;
} myTemps;

//function prototypes
void loadData(ifstream &infile, Temperature[], int &size);
Temperature averageHigh(Temperature[], int size);
Temperature averageLow(Temperature[], int size);


int main()
{
	
	ifstream infile("temps.txt");
	double average1, sum1 = 0, average2, sum2 = 0, highest1 = 0, index1, lowest1 = 0, index2; 
	
	void loadData(ifstream &inFile, Temperature[], int &size);
	
	Temperature averageHigh(Temperature, int &size);
	cout << index1 << endl;

	Temperature averageLow(Temperature, int &size);
	cout << index2 << endl;

	//end program
	cin.ignore(100, '\n');
	cout << "Press any key to continue: " << endl;
	getchar();
	return 0;
}

void loadData(ifstream & inFile, Temperature[], int & size)
{
	while(!inFile.eof())
	{
		for (int size = 0; size < 12; size++)
		{
			inFile >> myTemps[size].month >> myTemps[size].highTemp >> myTemps[size].lowTemp;
			size++;
		}
		return size;
	}
}

Temperature averageHigh(Temperature[], int size)
{
	int largest = 0;
	for (int ii = 0; ii < arraySizeL; ii++)
	{
		if (arrayL[ii] >= arrayL[largest]) largest = ii;
	}
	return largest;
}
Temperature averageHigh(Temperature[][2], double highest, double & index)
{
	highest = 0;
	for (int i = 0; i < 12; i++)
	{
		if (myTemps[i] > highest)
		{
			highest = myTemps[i];
			index = i;
		}
	}
}

Temperature averageLow(Temperature[][2], double lowest, double &index)
{
	lowest = 0;
	for (int i = 0; i < 12; i++)
	{
		if (myTemps[i][0] < lowest)
		{
			lowest = myTemps[i][0];
			index = i;
		}
	}
}
Your function signatures look wrong to me. Temperature is a type, just like int. You need to give those function parameters names, just like you do the int and double parameters.
Hi,

First get your code to compile. Press the gear icon at the top left of your code, turn on all 3 warning levels, then run. It will show the compilation errors.

while(!inFile.eof())

Just wondering who taught you to do that?

Consider using an unsigned type for the size of arrays.

Declare and intitialise your variables one per line. Ideally wait until you have a sensible value to assign. Always initialise every variable to something: unitinitialised variables are a big trap.

What is the concept of a function that returns a value? What are the 2 things needed for this to work? If a function shouldn't return a value, what is it's return type?

What is necessary for function overloading? How does the compiler know which one to execute?

This part might seem pedantic: put the reference & next to the type, C++ is all about types. It's easier to read if both of them are together. So, like this:

Temperature averageLow(Temperature[][2], double lowest, double& index) {/*... */}

I am not the only one to make this recommendation, isocpp is where I learnt it from.
https://isocpp.org/wiki/faq/style-and-techniques
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

Good Luck !!

Hello DashMGJ,

According to your instructions you are missing your arrays. You have two choices for these arrays. You could define them as having a size of 12 using 0 - 11 or a size of 13 using elements 1 - 12 of the array and just skip element zero.

Line 29 is a repeated proto type not a function call. It really will not do anything except maybe give you an error or a warning at compile time. I think what you ment is: loadData(inFile, unDefinedVariable, size) where "unDefinedVariable" is the array you have not defined yet.

In your two functions:
Temperature averageLow(Temperature[][2], double lowest, double &index) as MikeyBoy said "Temperatur" is a type and is missing a variable name. Also in the function definitions you are describing a 2D array when the proto type is describing a 1D array. The proto type and function defiition need to match.

Lines 31 and 34 are not function calls the use of "Temperatur" is not needed, just the function name and the parameters which is only the names of the variables passed.

Points 2, 3 and 4 describe the function proto types only. When you get to the function definition you will need to add to what is in the proto type to make it work.

The program needs to read an input file. If there is a link to this file please post it otherwise post at least a sample of this file, so everyone will know what you are working with. Just a few, 3 to 5, or ten will help.

Hope that helps,

Andy
Hello DashMGJ,

while(!inFile.eof())

I do not know why people teach this either. This is a bad idea as it does not work the way you think it will. Usually by the time the while condition determines that "eof" has been reached you will have processed the last read twice and wondering why it shows up twice.

A more acceptable way of using the while loop is:

1
2
3
4
5
6
7
while (infile >> someVariable)
{
    infile >> additionalVariables;

    //  Additional code.

}


My first thought was that the while loop might be an endless loop or that the for loop might overwrite the values in the array the second time through the while loop. When I tried it with the for loop it changed values in the array before the while loop ended. Removing the for loop seamed to work. The above code would do a much better job though.

The other thing about the "loadData" function is that you are not accessint the struct variables correctly. "myTemps" is a single struct and you are trying to access it as if it is an array. This does not work. You need to create an array of structs in main and use that variable to pass to the function and use in the function.

The first thing you need to do is get the read working correctly and you will have a better idea of how to correct the other two functions.

I also find the examples in the instructions, namely parts 3 and 4, are a little misleading and over done for what you could do. So, my question is do you have to use exactly what is there or are these just suggestions? I ask because there is a less involved way of using the return value.

Hope that helps,

Andy

Thank you all so much for your speedy responses!!
I'm already down to just 2 errors! ^.^

Now I just need to know what and how to return from my averageHigh and Low functions

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

using namespace std;

//struct data type - Temperature
struct Temperature
{
	string month;
	int highTemp;
	int lowTemp;
}myTemps[12];

//function prototypes
void loadData(ifstream &infile, Temperature[], int &size);
Temperature averageHigh(Temperature[], int size);
Temperature averageLow(Temperature[], int size);


int main()
{
	
	ifstream infile("temps.txt");
	double average1 = 0;
	double sum1 = 0;
	double average2 = 0;
	double sum2 = 0;
	double highest1 = 0;
	double index1 = 0;
	double lowest1 = 0;
	double index2;
	
	void loadData(ifstream &inFile, Temperature[], int &size);
	
	Temperature averageHigh(Temperature, int &size);
	cout << index1 << endl;

	Temperature averageLow(Temperature, int &size);
	cout << index2 << endl;

	//end program
	cin.ignore(100, '\n');
	cout << "Press any key to continue: " << endl;
	getchar();
	return 0;
}

void loadData(ifstream & inFile, Temperature[], int & size)
{
	while(inFile >> myTemps[size].month)
	{
		inFile >> myTemps[size].highTemp >> myTemps[size].lowTemp;
		size++;
	}
}

Temperature averageHigh(Temperature[], double highest, double & index)
{
	highest = 0;
	for (int i = 0; i < 12; i++)
	{
		if (myTemps[i].highTemp > highest)
		{
			highest = myTemps[i].highTemp;
			index = i;
		}
		return index;
	}
}

Temperature averageLow(Temperature[], double lowest, double &index)
{
	lowest = 0;
	for (int i = 0; i < 12; i++)
	{
		if (myTemps[i].lowTemp < lowest)
		{
			lowest = myTemps[i].lowTemp;
			index = i;
		}
	}
}
Here is my text file, temps.txt:
1
2
3
4
5
6
7
8
9
10
11
12
January 47 36
February 51 37
March 57  39
April 62 43
May 69 48
June 73 52
July 81 56
August 81 57
September 75 52
October 64 46
November 52 41
December 45 35
Hello DashMGJ,

Thank you for the input file. It is a big kelp.

The "loadData" function is better, but still not right.The function definition on line 51 still looks like a proto type not a function definition. It should be:
void loadData(ifstream & inFile, Temperature arrayName[], int & size). Where "arrayName" is the array you have not defined yet. Inside the function "myTemps" is not an array, but a single object of the struct. This will not work and should have given you compile errors.

Line 36 is a prototype not a function call. It should be: loadData(inFile, arrayName, size);. Just the names are needed. Try reading this:
http://www.cplusplus.com/doc/tutorial/functions/

For the other two functions they are set up to return an entire struct. This is over kill when all you need it to return an index to the array you need to define in main. You will need to change the return value of "Temperature" to "int" and then use "index1" and "index2" to receive the return values of the functions. Using "index1" and "index2" you can access the array to print the highest and lowest temps and the month that they are in.

The code for "averageHigh" is mostly correct except you are using the variable with "myTemps". "myTemps" is not an array. The same for "averageLow" function.

In the "agerageLow" function setting "lowest to zero to start with will be a problem. What happens when none of your low temps are below zero? I like to set this variable to a number higher than anything you would expect to find in the low temps. I used "100" in my version.

Lines 60 and 74 are the wrong way to write the function definition and you are using variables in the parameters you do not need. "highest" and "lowest" should be defined in the function not the parameters. Just as an idea this is the function definition that I used: int AverageLow(Temperature temps[], int size). "size" does not need to be passed by reference because the function should not ever change this variable. The better definition would be:
int AverageLow(Temperature temps[], const int size). Since you are only using "size" not changing it.

In main you have defined all the numeric variables as doubles. Only "avgerge1" and "averge2", if ever used need to be a double. All the other variables would be fine as "int"s.

Line 26 defines and opens the file stream. After that you should check that the file has been opened before trying to use it.

You still need to define an array of structs in main.

Hope that helps,

Andy

Edit: My apologies I finally noticed where you did make an array of "myTemps". I was not expecting it where you defined it. I will have to try your new code to see how it works.
Last edited on
Hello DashMGJ,

When I compiled your program I received several warnings and several errors.

It complained about line 36 being a prototype not a functions call.

Next the other warnings are about the variables in main that are initialized, but never used.

In the "avergeHigh" function you return a double, which is OK, but the function is expecting to return a struct. The return type of the function needs to match the type of the return statement. And it only needs to be an int not a double.

The "averageLow" function does not return anything.

These errors need to be addressed before the program cn be tested.

Hope that helps,

Andy
Ok, now I'm really confused because the compiler went from 2 to 33 errors.
Here's what I have so far:
Have I declared my array properly?
If you have a working version of my code, please show me because that is a better way for me to learn. I'm not asking you to do the work for me, I'm asking to show so that I can learn from it. Telling me what to do is like reading the compiler error. It tells me what's wrong, but not where to go from there.
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
//Dash Justice
//CS 161
//Assignment 7
//sources: recieved help from cplusplus.com forum
//

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <istream>

using namespace std;

//struct data type - Temperature
struct Temperature
{
	string month;
	int highTemp;
	int lowTemp;
}myTemps;

//function prototypes
void loadData(ifstream &infile, Temperature[], int &size);
int averageHigh(Temperature[], int size);
int averageLow(Temperature[], int size);


int main()
{
	Temperature temps[12];
	ifstream infile("temps.txt");

	//variables
	int highest = 0;
	double index1 = 0;
	int lowest = 0;
	double index2 = 0;
	
	void loadData(inFile, myTemps, size);
	
	int AverageHigh(Temperature temps[], int highest, int index1);
	cout << index1 << endl;

	int averageLow(Temperature temps[], int lowest, int index2);
	cout << index2 << endl;

	//end program
	cin.ignore(100, '\n');
	cout << "Press any key to continue: " << endl;
	getchar();
	return 0;
}

void loadData(inFile, temps[], size)
{
	while(inFile >> myTemps[size].month)
	{
		inFile >> myTemps[size].highTemp >> myTemps[size].lowTemp;
		size++;
	}
}

int AverageHigh(Temperature temps[], highest, int index1)
{
	int highest = 0;
	for (int i = 0; i < 12; i++)
	{
		if (myTemps[i].highTemp > highest)
		{
			highest = myTemps[i].highTemp;
			index1 = i;
		}
		return index1;
	}
}

int AverageLow(Temperature temps[], lowest, int size)
{
	lowest = 0;
	for (int i = 0; i < 12; i++)
	{
		if (myTemps[i].lowTemp < lowest)
		{
			lowest = myTemps[i].lowTemp;
			index2 = i;
		}
		return index2;
	}
}


Thank you so much for your help! ^.^
Oky I got the code working but now all it displays is 0
I have one day to get the rest of this done >.<
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
//Dash Justice
//CS 161
//Assignment 7
//sources: recieved help from cplusplus.com forum
//

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <istream>

using namespace std;

//struct data type - Temperature
struct Temperature
{
	string month;
	int highTemp;
	int lowTemp;
};

//function prototypes
void loadData(ifstream &infile, Temperature[], int &size);
int averageHigh(Temperature[], int size);
int averageLow(Temperature[], int size);


int main()
{
	Temperature temps[12];
	ifstream infile("temps.txt");

	//variables
	int highest = 0;
	int lowest = 0;
	int index2 = 0;
	int index1 = 0;
	
	void loadData(ifstream inFile, Temperature temps, int size);
	
	int averageHigh(Temperature temps[], int highest, int index1);
	cout << index1 << endl;

	int averageLow(Temperature temps[], int lowest, int index2);
	cout << index2 << endl;

	//end program
	cin.ignore(100, '\n');
	cout << "Press any key to continue: " << endl;
	getchar();
	return 0;
}

void loadData(ifstream &inFile, Temperature temps[], int &size)
{
	while(inFile >> temps[size].month)
	{
		inFile >> temps[size].highTemp >> temps[size].lowTemp;
		size++;
	}
}

int averageHigh(Temperature temps[], int highest, int index1)
{
	for (int i = 0; i < 12; i++)
	{
		if (temps[i].highTemp > highest)
		{
			highest = temps[i].highTemp;
			index1 = i;
		}
		return index1;
	}
}

int averageLow(Temperature temps[], int lowest, int index2)
{
	
	for (int i = 0; i < 12; i++)
	{
		
		if (temps[i].lowTemp < lowest)
		{
			lowest = temps[i].lowTemp;
			index2 = i;
		}
		return index2;
	}
}
I fixed it up a bit more but I'm still stuck :/

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
//Dash Justice
//CS 161
//Assignment 7
//sources: recieved help from cplusplus.com forum
//

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <istream>

using namespace std;

//struct data type - Temperature
struct Temperature
{
	string month;
	int highTemp;
	int lowTemp;
};

//function prototypes
void loadData(ifstream &infile, Temperature[], int &size);
int averageHigh(Temperature[], int size);
int averageLow(Temperature[], int size);


int main()
{
	Temperature temps[12];
	ifstream infile("temps.txt");

	//variables
	int highest = 0;
	int lowest = 0;
	int index2 = 0;
	int index1 = 0;
	
	void loadData(ifstream &inFile, Temperature temps[], int &size);
	
	int averageHigh(Temperature temps[], int highest, int index1);
	cout << "The hottest month this year was " << temps[index1].month << " with a temperature of " << temps[index1].highTemp << endl;

	int averageLow(Temperature temps[], int lowest, int index2);
	cout << "The coldest month this year was " << temps[index2].month << " with a temperature of " << temps[index2].lowTemp << endl;

	//end program
	cin.ignore(100, '\n');
	cout << "Press any key to continue: " << endl;
	getchar();
	return 0;
}

void loadData(ifstream &inFile, Temperature temps[], int &size)
{
	while(!inFile.eof())
	{
		inFile >> temps[size].month >> temps[size].highTemp >> temps[size].lowTemp;
		size++;
	}
}

int averageHigh(Temperature temps[], int highest, int index1)
{
	for (int i = 0; i < 12; i++)
	{
		if (temps[i].highTemp > highest)
		{
			highest = temps[i].highTemp;
			index1 = i;
		}
		return index1;
	}
}

int averageLow(Temperature temps[], int lowest, int index2)
{
	
	for (int i = 0; i < 12; i++)
	{
		
		if (temps[i].lowTemp < lowest)
		{
			lowest = temps[i].lowTemp;
			index2 = i;
		}
		return index2;
	}
}
Hello DashMGJ,

OK this last bit of code is very close. I hope you can see the differences between your code and mine.

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
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
//#include <istream>  // <--- Not needed. "<fstream>" is all you need.

using namespace std;

//struct data type - Temperature
struct Temperature
{
	string month;
	int highTemp;
	int lowTemp;
}myTemps[12];  // <--- "myTemps" should be defined in main not here.

//function prototypes
void loadData(ifstream &infile, int &size);
int averageHigh(const int size);
int averageLow(const int size);


int main()
{

	ifstream infile("temps.txt");
	// These variables not used right now.
	//double average1 = 0;
	//double average2 = 0;
	//int sum1 = 0;
	//int sum2 = 0;
	//int highest1 = 0;
	//int lowest1 = 0;

	int index1 = 0;
	int index2{};
	int size{};
	
	loadData(infile, size);  // <--- "myTemeps" is defined a a global variable and does not need to be passed here. Same for "averageHigh" and "averageLow".

	index1 =  averageHigh(size);
	//cout << index1 << endl;  // This line not really needed.
	std::cout << "\n The average high tempature is " << myTemps[index1].highTemp << " degres in " << myTemps[index1].month << '.' << std::endl;

	index2 = averageLow(size);
	//cout << index2 << endl;  // This line not really needed.
	std::cout << "\n The average low tempature is " << myTemps[index2].lowTemp << " degres in " << myTemps[index2].month << '.' << std::endl;

	//end program
	cout << "\n\n Press Enter to continue: ";  // <--- Changed message and removed the "endl".
	cin.ignore(100, '\n'); // <--- Not needed here. Better to use than "getchar()". Will wait for enter only.
	//getchar();  // <--- Waits for enter only. Only one is needed. The above line is a better choice.

	return 0;
}

void loadData(ifstream & inFile, int & size)
{
	while (inFile >> myTemps[size].month)
	{
		inFile >> myTemps[size].highTemp >> myTemps[size].lowTemp;
		size++;
	}
}

int averageHigh(const int size)
{
	int highest = 0;
	int index{};

	for (int i = 0; i < size; i++)
	{
		if (myTemps[i].highTemp > highest)
		{
			highest = myTemps[i].highTemp;
			index = i;
		}
	}
	
	return index;
}

int averageLow(const int size)
{
	int lowest = 110;
	int index{};

	for (int i = 0; i < size; i++)
	{
		if (myTemps[i].lowTemp < lowest)
		{
			lowest = myTemps[i].lowTemp;
			index = i;
		}
	}

	return index;
}


Hope that helps,

Andy
But your code just outputs 0
Print the 'size' on line 40. I bet you will get 0 due to program not actually getting any data. Perhaps the current working directory on your test run does not contain the data file.


What is the logic of the function names: average***? The names do not match to what the functions do. Names do not have to match, but if they do, then they make reading the code more intuitive.



Note: C++ Standard Library has
http://www.cplusplus.com/reference/algorithm/max_element/
http://www.cplusplus.com/reference/algorithm/min_element/
that perform the same work as "averageHigh" and "averageLow" in more generic fashion.
I got it to work thank you all so much!!! ^.^
Topic archived. No new replies allowed.