Newbie Homework Help Program 2

M

mattcshort

Ok here's another program I have somewhat working. It runs fine if I
don't cause it to invalidate my input, but if I enter a number greater
than 32 when it goes to calculate the high and low months I get a
memory error. There's a sample at the bottom that shows it works with
valid input.

The error: The instruction at "xxxxxxx" referenced memory at "xxxxxx".
The memory could not be "read".

I'm pretty sure it has something to do with the way I am validating my
input, but one thing I am trying to avoid is having it says what valid
input IS every time it asks. An if statement would clear that up, but I
thought it redundant to have the while loop validating AND the if
statment validating.


Thanks,

Matt


Here's my code so far:

/*

Program 6: Program number 2 on page 473
C++ 171-01
Program Description:This program lets the user enter the total rainfall
for each of 12 months into an array.
Variables: count for counters,
month is the array for the months,
high is the subscript of the month array
total is the total rainfall,
average is the average rainfall
name is the of the array of months within
size is the size of the array
highLow is the test value for the function


Functions: displayMessage: asks for the rainfall for each month
totalAmount calculates the total amount of rainfall
averageAmount calculates the average rainfall
displayValue calculates the high and low months

*/

#include <iostream>
using namespace std;

double displayMessage (char name[]);
double totalAmount (double amount[], int size);
double averageAmount (double amount[], int size);
int displayValue(double amount[], int size, int highLow);

int main()
{
char month[12][10] = { "January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"};
double amount[12];
int high;
double total, average;

for (int count = 0; count <12; count++)
{
amount[count] = displayMessage (month[count]);
}

total = totalAmount(amount, 12);
cout << "\nThe total rainfall for the year is: " << total << endl;

average = averageAmount (amount, 12);
cout << "The average rainfall for the year is: " << average << endl;

high = displayValue(amount, 12, 1);
cout << endl << "The month with the highest rain is " << month[high]
<< " with the amount of " << amount[high] << endl;

high = displayValue(amount, 12, 0);
cout << endl << "The month with the lowest rain is " << month[high] <<
" with the amount of " << amount [high] << endl;

return 0;
}


double displayMessage (char name[])
{
double rainfall;

while (rainfall < 0.0 || rainfall > 32.0)
{
cout << "Enter the rainfall for " << name << " : "; cin >>
rainfall;
cout << "\nRainfall must be between 0 and 32\n";
}

return rainfall;
}

double totalAmount (double amount[], int size)
{
int total =0;
for (int count =0; count < size; count++)
total += amount[count];
return total;
}

double averageAmount (double amount[], int size)
{
double total = 0;
double average;
for (int count =0; count < size; count++)
total += amount[count];
average = total/size;
return average;
}


int displayValue(double amount[], int size, int highLow)
{
int count;
int highest;
int big=0;
int lowest;
int high;

if (highLow == 0)
{
lowest = amount[0];
for (count=1; count < size; count++)
{
if (amount[count] < lowest)
{
lowest = amount[count]; high = count;
}
}
}
else
{
highest = amount[0];
for (count = 1; count < size; count++)
{
if (amount[count] > highest)
{
highest = amount[count];high=count;
}
}
}
return high;
}

/*

Enter the rainfall for January : 2
Enter the rainfall for February : 2
Enter the rainfall for March : 2
Enter the rainfall for April : 2
Enter the rainfall for May : 2
Enter the rainfall for June : 2
Enter the rainfall for July : 2
Enter the rainfall for August : 2
Enter the rainfall for September : 2
Enter the rainfall for October : 2
Enter the rainfall for November : 1
Enter the rainfall for December : 30

The total rainfall for the year is: 51
The average rainfall for the year is: 4.25

The month with the highest rain is December with the amount of 30

The month with the lowest rain is November with the amount of 1
Press any key to continue


*/
 
V

Victor Bazarov

Ok here's another program I have somewhat working. It runs fine if I
don't cause it to invalidate my input, but if I enter a number greater
than 32 when it goes to calculate the high and low months I get a
memory error. There's a sample at the bottom that shows it works with
valid input.

The error: The instruction at "xxxxxxx" referenced memory at "xxxxxx".
The memory could not be "read".

I'm pretty sure it has something to do with the way I am validating my
input, but one thing I am trying to avoid is having it says what valid
input IS every time it asks. An if statement would clear that up, but
I thought it redundant to have the while loop validating AND the if
statment validating.

See below. I have not found any reason for memory errors _except_ that
you're using uninitialised variables. Such use *in general* causes
undefined behaviour, so I am guessing that it's possible that it caused
memory errors like you reported. Fix it and try again.
Thanks,

Matt


Here's my code so far:

Sorry for losing your formatting. OE isn't capable of quoting correctly
if the quoted text has tab characters in it. (BTW, that's why I switched
to using spaces in *all* my text editors).
/*

Program 6: Program number 2 on page 473
C++ 171-01
Program Description:This program lets the user enter the total
rainfall for each of 12 months into an array.
Variables: count for counters,
month is the array for the months,
high is the subscript of the month array
total is the total rainfall,
average is the average rainfall
name is the of the array of months within
size is the size of the array
highLow is the test value for the function


Functions: displayMessage: asks for the rainfall for each month
totalAmount calculates the total amount of rainfall
averageAmount calculates the average rainfall
displayValue calculates the high and low months

*/

#include <iostream>
using namespace std;

double displayMessage (char name[]);
double totalAmount (double amount[], int size);
double averageAmount (double amount[], int size);
int displayValue(double amount[], int size, int highLow);

int main()
{
char month[12][10] = { "January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"};
double amount[12];
int high;
double total, average;

for (int count = 0; count <12; count++)
{
amount[count] = displayMessage (month[count]);
}

total = totalAmount(amount, 12);
cout << "\nThe total rainfall for the year is: " << total << endl;

average = averageAmount (amount, 12);
cout << "The average rainfall for the year is: " << average << endl;

high = displayValue(amount, 12, 1);
cout << endl << "The month with the highest rain is " << month[high]
<< " with the amount of " << amount[high] << endl;

high = displayValue(amount, 12, 0);
cout << endl << "The month with the lowest rain is " << month[high] <<
" with the amount of " << amount [high] << endl;

return 0;
}


double displayMessage (char name[])
{
double rainfall;

You didn't initialise the 'rainfall' here and you're checking its value
in the next statement. You need give it an invalid value.
while (rainfall < 0.0 || rainfall > 32.0)
{
cout << "Enter the rainfall for " << name << " : "; cin >>
rainfall;

You might want to display the following message _only_ if 'rainfall'
is invalid.
cout << "\nRainfall must be between 0 and 32\n";
}

return rainfall;
}

double totalAmount (double amount[], int size)
{
int total =0;
for (int count =0; count < size; count++)
total += amount[count];
return total;
}

double averageAmount (double amount[], int size)
{
double total = 0;
double average;
for (int count =0; count < size; count++)
total += amount[count];
average = total/size;
return average;
}


int displayValue(double amount[], int size, int highLow)
{
int count;
int highest;
int big=0;
int lowest;
int high;

if (highLow == 0)
{
lowest = amount[0];
for (count=1; count < size; count++)
{
if (amount[count] < lowest)
{
lowest = amount[count]; high = count;
}
}
}
else
{
highest = amount[0];
for (count = 1; count < size; count++)
{
if (amount[count] > highest)
{
highest = amount[count];high=count;
}
}
}
return high;

If you're calculaing 'low' (highLow == 0), and the lowest is January,
then you're returning a variable without ever initialising it. You
need to give it a value 0, I recon.
}

/*

Enter the rainfall for January : 2
Enter the rainfall for February : 2
Enter the rainfall for March : 2
Enter the rainfall for April : 2
Enter the rainfall for May : 2
Enter the rainfall for June : 2
Enter the rainfall for July : 2
Enter the rainfall for August : 2
Enter the rainfall for September : 2
Enter the rainfall for October : 2
Enter the rainfall for November : 1
Enter the rainfall for December : 30

The total rainfall for the year is: 51
The average rainfall for the year is: 4.25

The month with the highest rain is December with the amount of 30

The month with the lowest rain is November with the amount of 1
Press any key to continue


*/


V
 
K

Kasimir

The error: The instruction at "xxxxxxx" referenced memory at "xxxxxx".
The memory could not be "read".

I cant't find any reason, why you are getting this out of bounds error,
but you are using a undefined variable, might be that's the reason for
it.

I provide a changed version of your code:

#include <iostream>
#include <vector>
using namespace std;

double inputMonthlyRainfall (const char* month);
// name of function represents its task
double totalAmount (const vector<double>& amount);
double averageAmount (const vector<double>& amount);
int maxAmountIndex (const vector<double>& amount);
int minAmountIndex (const vector<double>& amount);
// names changed: there was no reason to use only one function

int main_()
{
const char* const month[12] = {
// array of const pointers to const instead of two-dim-array
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};

vector<double> amount;
// use a vector if not advised to do other
for (int count = 0; count < 12; count++)
{
amount.push_back( inputMonthlyRainfall (month[count]) );
}

cout << endl
<< "The total rainfall for the year is: "
<< totalAmount (amount);
// getting rid of temporary

cout << endl
<< "The average rainfall for the year is: "
<< averageAmount (amount)
// getting rid of temporary
<< endl;

int high = maxAmountIndex (amount);
cout << endl
<< "The month with the highest rain is "
<< month[high]
<< " with the amount of "
<< amount[high]
<< endl;

int low = minAmountIndex (amount);
cout << endl
<< "The month with the lowest rain is "
<< month[low]
<< " with the amount of "
<< amount[low]
<< endl;

return 0;
}

double inputMonthlyRainfall (const char* month)
{
for ( ;; ) {
// indefinite loop helps displaying error message
// only when needed
cout << "Enter the rainfall for " << month << " : ";
double rainfall;
cin >> rainfall;
if (rainfall >= 0.0 && rainfall <= 32.0)
return rainfall;
cout << endl << "Rainfall must be between 0 and 32" << endl;
}
}

double totalAmount (const vector<double>& amount)
{
double total = 0;
for (unsigned count = 0; count < amount.size(); count++)
total += amount[count];
return total;
}

double averageAmount (const vector<double>& amount)
{
// don't repeat yourself: you've got a function to calculate
// totalAmount already
// getting rid of temporaries
return totalAmount( amount ) / amount.size();
}

int maxAmountIndex (const vector<double>& amount)
{
int high = 0;
for (unsigned count = 1; count < amount.size(); count++)
if (amount[count] > amount[high])
high = count;
return high;
}

int minAmountIndex (const vector<double>& amount)
{
int low = 0;
for (unsigned count = 1; count < amount.size(); count++)
if (amount[count] < amount[low])
low=count;
return low;
}


HTH
--
 
M

mattcshort

Whoa, Kasimir, you didn't need to do all that :)

Hmm, one of the things you did is the cout formatting vs. mine. Your
layout is much easier on the eyes.

I'm wondering if you and Victor are talking about the rainfall variable
not being initialized to 0 just above my while loop. If that's true I
tried changing it earlier today and the results ended up being worse.

Maybe I'll run it on a different computer and see if it works. I'll
look more into your data validation as well because I don't like the
way I did it.

Thanks guys,

Matt
 
V

Victor Bazarov

Whoa, Kasimir, you didn't need to do all that :)

Hmm, one of the things you did is the cout formatting vs. mine. Your
layout is much easier on the eyes.

I'm wondering if you and Victor are talking about the rainfall
variable not being initialized to 0 just above my while loop. If
that's true I tried changing it earlier today and the results ended
up being worse.

I didn't say anything about 0. You need to initialise it with a value
that your algorithm considers _invalid_, so that the execution actually
does go into the 'while' loop.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top