C++ program 2 help

laserpp

Distinguished
Nov 29, 2008
137
0
18,630
Okay, found out how to get the months to display when entering the rainfall but I cant figure out how to get it to display the name of the month for the lowest and highest rainfall( Lines 51 and 66). The way I have it when I enter the last rainfall it displays the total and average then beeps and shows weird characters for the highest and lowest.

Code:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

double total;

int main()
{
	const int array_size = 12;
	string name[array_size] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
	double rain[array_size];
	int count;
	double average;
	double lowest;
	double highest;

	cout << "Please enter the rainfall for all 12 months" << endl;
	cout << "After each input please press enter to input the next number" << endl << endl;
	for (count = 0; count < array_size; count++)
	{
		cout << "Please enter " << name[count] << " rainfall: ";
		cin >> rain[count];
			if (rain[count] < 0)
			{
				cout << "Rainfall can not be a negative number" << endl;
				cout << "Please re-enter " << name[count] << " rainfall: ";
				
				cin >> rain[count];
			}
			total += rain[count];
	}
	
	average = total/12;

	cout << "The total rainfall for the year is: " << total << endl;
	cout << "The average rainfall for the year is: " << average << endl;

	
	highest = rain[0];
	for (count = 1; count < array_size; count++)
	{
		if (rain[count] > highest)
		{
			highest = rain[count];
		}
		
	}
	cout << "The highest rainfall is in " << name[count] << " with: " << highest << " inches" << endl;



	
	
	lowest = rain[0];
	for (count = 1; count < array_size; count++)
	{
		if (rain[count] < lowest)
		{
			lowest = rain[count];
		}
		
	}
	cout << "The lowest rainfall is in " << name[count] << " with: " << lowest << " inches" << endl;







	return 0;
}
 

flamethrower205

Distinguished
Jun 26, 2001
187
0
18,630
The error you're making is in your use of the count variable. If this were a managed language you'd get an index out of bounds exception, but C++ is just letting you access some random piece of the address space. In the for loop to find the highest rain count, you determine the largest amount of rain. However, you do not determine the index of this month. Later, when you cout, name[count] is actually asking for name[12], which is not within your array!
What you want is to declare
int highest_index = 0;
and have
if (rain[count] > highest)
{
highest = rain[count];
highest_index = count;
}

Then when you cout, ask for name[highest_index]
Likewise for the lowest rainfall.
Cheers,
 

laserpp

Distinguished
Nov 29, 2008
137
0
18,630
One last question, I made the total variable a global because when I had it as a local it didn't recognize my running total (line 31). I know its find to have as a global but just confused why it wasn't working as a local.
 

Zenthar

Distinguished
Dec 31, 2007
250
0
18,960
Good solution there, but you can go a bit further. Since you keep the index of the highest rainfall, you don't need to also keep the value.
Code:
int highest_index = 0;
...
if (rain[count] > rain[highest_index])
{
    highest_index = count;
}
Then if you need the month name, use "name[highest_index]" as suggested and for the value "rain[highest_index]".
 

flamethrower205

Distinguished
Jun 26, 2001
187
0
18,630
I think the difference in code is in part stylistic, I prefer to be upfront about what I'm keeping track of since it's one less thing to worry about when implementing some heinous algorithm.
Keeping track of the local variable also helps performance though (I do a lot of high performance code in which saving a couple of cycles or memory accesses can result in hours less processing time).
To that end, you can minimize array accesses by directly keeping track of the best value. You'll also help the compiler realize that it ought to cache highest.
I did a small test to find the smallest element in a random array of 10^7 elements in which code 1 explicitly stores the value of the smallest element while code 2 refers to the array for the value (as in you suggestion). The average runtimes with managed and unmanaged code, respectively, are

Managed:
Code 1 - 51.9 ms
Code 2 - 90.6 ms

Unmanaged:
Code 1 - 36.8
Code 2 - 44.6

Thus, keeping track of the best value gives you a 42.7% and 17.5% performance advantage for managed and unmanaged code, respectively. Granted this makes no difference with 12 elements, but it's good coding practice for larger programs.
 

mindless728

Distinguished
Jul 15, 2008
130
0
18,660


it's because he is using total without initializing it, ie he is declaring it without setting it, and then in line 31 using it

line 6 should be:
Code:
double total = 0;
 

flamethrower205

Distinguished
Jun 26, 2001
187
0
18,630
O it's definitely sketchy business, especially in C++. it's just amusing that the compiler didn't care when he declared it (but didn't explicitly initialize) as a global variable - technicalities of the language aside, more user consistency from the compiler would be nice.