Here is the program in C++ about Weather Statistics. This program uses a structu
ID: 3813152 • Letter: H
Question
Here is the program in C++ about Weather Statistics. This program uses a structure to store the following weather data for a particular month
Total Rainfall
High Temperature
Low Temperature
Average Temperature
The program uses an array of 12 structures to hold weather data for an entire year. When the program runs, it asks the user to enter data (Total Rainfall, High Temperature, Low Temperature) for each month. (The average temperature should be calculated) Once the data are entered for all the months, the program should calculate and display the average monthly rainfall, the total rainfall for the year, the highest and lowest temperatures for the year and (the months they occurred in), and the average of all the monthly average temperatures.
Note: the temperature should be in the range [-100, 140]
Please revise this program as following:
When user input high temperature and low temperature for each month, the high temperature should be higher or equal to low temperature, if not, the program will display “ERROR: high temperature should be higher or equal to the low temperature” and asks user to input high temperature and low temperature again, if the new high temperature is still lower than the low temperature, the program will display “ERROR: high temperature should be higher or equal to the low temperature” and asks user to input high temperature and low temperature again, until the current high temperature is higher or equal to the low temperature, the program will continue to execute the next statement.
Note: the temperature should be in the range [-100, 140]
Here is the original program:
// Weather Statistics
#include
using namespace std;
// Constant for the number of months
const int NUM_MONTHS = 12;
// Declaration of the WeatherInfo structure
struct WeatherInfo
{
double rain; // Total rainfall
double high; // High temperature
double low; // Low temperature
double averageTemp; // Average temperature
};
int main()
{
// Create an array of WeatherInfo structures
WeatherInfo year[NUM_MONTHS];
int index = 0; // Loop counter
// Get the weather data for each month.
cout << "Enter the following information: ";
for (index = 0; index < NUM_MONTHS; index++)
{
// Get the rainfall.
cout << "Month " << (index + 1) << endl;
cout << " Total Rainfall: ";
cin >> year[index].rain;
// Get the high temperature.
cout << " High Temperature: ";
cin >> year[index].high;
// Validate the high temperature.
while (year[index].high < -100 || year[index].high > 140)
{
cout << "ERROR: Temperature must be in the range "
<< "of -100 through 140. ";
cout << " High Temperature: ";
cin >> year[index].high;
}
// Get the low temperature.
cout << " Low Temperature: ";
cin >> year[index].low;
// Validate the high temperature.
while (year[index].low < -100 || year[index].low > 140)
{
cout << "ERROR: Temperature must be in the range "
<< "of -100 through 140. ";
cout << " Low Temperature: ";
cin >> year[index].low;
}
// Calculate the average temperature.
year[index].averageTemp =
(year[index].high + year[index].low) / 2.0;
}
// Calculate total annual rainfall
double totalRain = 0;
for (index = 0; index < NUM_MONTHS; index++)
totalRain += year[index].rain;
// Calculate average monthly rainfall
double aveMonthRain = totalRain / NUM_MONTHS;
// Calculate the average monthly average temperature
double aveTotal = 0, aveAve;
for (index = 1; index < NUM_MONTHS; index++)
aveTotal += year[index].averageTemp;
aveAve = aveTotal / NUM_MONTHS;
// Find the highest & lowest temperatures
double highest, lowest, highMonth = 0, lowMonth = 0;
highest = year[0].high;
lowest = year[0].low;
for (index = 1; index < NUM_MONTHS; index++)
{
if (year[index].high > highest)
{
highest = year[index].high;
highMonth = index;
}
if (year[index].low < lowest)
{
lowest = year[index].low;
lowMonth = index;
}
}
// Display findings.
cout << " Total Rainfall: " << totalRain << endl;
cout << "Average Monthly Rain: " << aveMonthRain << endl;
cout << "Average Monthly Average Temperature: " << aveAve << endl;
cout << "Highest Temperature: " << highest;
cout << " (Month " << (highMonth + 1) << ") ";
cout << "Lowest Temperature: " << lowest;
cout << " (Month " << (lowMonth + 1) << ") ";
return 0;
}
Explanation / Answer
This is the solution to the gven programmatical problem . Hope this would be easy to understand
I have modified a bit of your requirements and hope it would be helpful for you to solve your
query.
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
#include <math.h>
#include <conio.h>
#include <string.h>
fstream file;
char year[5]="";
//Non-Member function to find month, to avoid user data-entrychar *returnMonth(int m){
switch(m){
case 1 : return("January");
case 2 : return("February");
case 3 : return("March");
case 4 : return("April");
case 5 : return("May");
case 6 : return("June");
case 7 : return("July");
case 8 : return("August");
case 9 : return("September");
case 10 : return("October");
case 11 : return("November");
case 12 : return("December");
}
return("Invalid");
}
//Non-Member functions, checks for whether file is loaded or not//it returns 1 if not loaded and 0 otherwise.int checkFile(){
if(file==NULL){
cout<<" There is No Data to Display ";
getch();
return(1);
}
return(0);
}
class weather
{
public:
double avgtemp[12];
char month[12][20];
weather();
void getdata(int m)
{
strcpy(month[m],returnMonth(m)); //avoiding user to input
cout<<" Enter temperature for "<<month[m]<<" : ?";
cin>>avgtemp[m];
}
void displaydata(int m)
{
cout<<setw(20)<<setprecision(2)<<setiosflags(ios::left)
<<setiosflags(ios::showpoint)
<<month[m]<<setw(10)<<setiosflags(ios::right)<<avgtemp[m];
}
void displaytemp(int i)
{
//Display only Temperature data
cout<<setw(10)<<setprecision(2)<<setiosflags(ios::right)
<<setiosflags(ios::showpoint)<<avgtemp[i];
}
double returntemp(int i)
{
return(avgtemp[i]);
}
void loadfile();
void displaytempscale(); //for displaying temperature scalevoid updatedata(int m,double t)
{
strcpy(month[m],returnMonth(m));
avgtemp[m]=t;
}
int validate(double t){ //Validate entered temperature (change to suit ur requirement).if(t>55 || t < (-20))
return(1); //states that invalid entryelsereturn(0); //valid entry
}
};
weather :: weather()
{
//Constructor to intialize objectfor(int i=0;i<12;i++)
{
avgtemp[i]=0;
month[i][0]=NULL;
}
}
void weather :: loadfile()
{ //for Selecting Year or creation of new year file.
clrscr();
file.close(); //It is required when trying to open different year files,//while there is already loaded any year file.char filename[20]="";
cout<<" *****Select a Year to Work With***** ";
cout<<"Enter Year (eg: 2001) : ?";
cin>>year;
strcat(filename,"c:\"); //Here i am assuming that path must be c:
strcat(filename,"data"); //if u wan't to skip that criteria just remove this lines.
strcat(filename,year);
strcat(filename,".dat");
file.open(filename,ios::ate|ios::nocreate|ios::in|ios::out|ios::binary);
if(file==NULL)
{
char ans;
cout<<" File Dose Not Exist "
<<"Do you wan't to create it! (y or n) N : ?"; //By default No
ans=getche();
if(ans=='y'|| ans=='Y')
{
file.open(filename,ios::ate|ios::in|ios::out|ios::binary);
cout<<" File Created Successfully";
}
else
{
file;
cout<<" Fail to load data file";
}
}
else if(file!=NULL)
{
cout<<" Data File is successfully loaded";
}
getch();
}
void weather :: displaytempscale()
{
int i,c=0;
cout<<" ";
for(i=1;i<=70;i++)
{
if(i<=10)
cout<<"0";
else if(i<=20)
cout<<"1";
else if(i<=30)
cout<<"2";
else if(i<=40)
cout<<"3";
else if(i<=50)
cout<<"4";
else if(i<=60)
cout<<"5";
else if(i<=70)
cout<<"7";
}
cout<<" ";
for(i=1;i<=7;i++)
{
for(c=0;c<10;c++)
cout<<c;
}
cout<<" ";
}
void intro()
{
clrscr();
cout<<" ";
cout<<" Email : admin@syntax-example.com "
<<" Website : http://www.syntax-example.com";
cout<<" ";
cout<<"Thanks for using this software.";
getch();
}
void main()
{
char choice='1';
int cnt,i,j,iNum,totstars=0,location,m;
double decNum,dNum,high=0,low=99999,avg=0,t;
char c;
weather obj;
file.close();
do
{
clrscr();
cout<<" *****Main Menu***** ";
cout<<"1> Select a year to work with "
<<"2> Display data as Table "
<<"3> Display data as horizontal histogram "
<<"4> Display Yearly Statistics to date "
<<"5> Record Data "
<<"6> Change Data "
<<"7> Save Data "
<<"0> Exit "
<<"Please enter a number (0...7) => ";
choice=getche();
//again for sake of simplicity i have directly return code
//in case brace rather than going for member-function.
switch(choice)
{
case '0' : intro();
goto out;
case '1' : obj.loadfile();
break;
case '2' : clrscr();
cout<<" *****Display Data as a Table***** ";
if(checkFile()){
goto endtable;
}
cout<<" Table of Temperature data for "<<year;
cout<<" ";
file.seekg(0,ios::end);
cnt=file.tellg();
cnt=cnt/sizeof(obj); //cnt contains how many records previously recorded
file.seekg(0,ios::beg);
for(i=1;i<=cnt;i++)
{
if(i==1)
cout<<" Quater 1 : ";
else if(i==4)
cout<<" Quater 2 : ";
else if(i==7)
cout<<" Quater 3 : ";
else if(i==10)
cout<<" Quater 4 : ";
file.read((char *)&obj, sizeof(obj));
if(!file.eof()){
obj.displaytemp(i);
}
file.clear();
}
getch();
endtable:
break;
case '3' : clrscr();
cout<<" *****Display Data as a Horizontal Histogram***** ";
if(checkFile()){
goto endhistogram;
}
cout<<"Histogram of Temperature data for "<<year;
obj.displaytempscale();
file.seekg(0,ios::end);
cnt=file.tellg();
cnt=cnt/sizeof(obj); //cnt contains how many records previously recorded
file.seekg(0,ios::beg);
for(i=1;i<=cnt;i++)
{
cout<<" "<<setw(15)<<setiosflags(ios::left)<<returnMonth(i);
file.read((char *)&obj, sizeof(obj));
if(!file.eof()){
decNum=obj.returntemp(i);
iNum=floor(decNum);
dNum=decNum-iNum; //for finding decimal part.
totstars=iNum;
if(dNum >= 0.5)
totstars++;
for(j=1;j<=totstars;j++)
cout<<"*";
cout<<" "<<totstars;
}
file.clear();
}
obj.displaytempscale();
getch();
endhistogram:
break;
case '4' : clrscr();
cout<<" *****Display Yearly Statistics to Date***** ";
if(checkFile()){
goto endstatus;
}
cout<<"Temperature Statistics data for "<<year;
cnt=file.tellg();
cnt=cnt/sizeof(obj); //cnt contains how many records previously recorded
file.seekg(0,ios::beg);
high=avg=0;
low=99999;
for(i=1;i<=cnt;i++)
{
file.read((char *)&obj, sizeof(obj));
double tmp=obj.returntemp(i);
if(!file.eof()){
if(high < tmp)
high=tmp;
if(low > tmp)
low=tmp;
avg=avg+tmp;
}
file.clear();
}
avg=avg/double(cnt);
cout<<" Highest Monthly Average : "<<high;
cout<<" Lowest Monthly Average : "<<low;
cout<<" Average Yearly Temperature : "<<avg;
getch();
endstatus:
break;
case '5' : clrscr();
cout<<" *****Record Data***** ";
if(checkFile()){
goto endRecord;
}
else{
cnt=file.tellg();
cnt=cnt/sizeof(obj); //cnt contains how many records previously recorded
if(cnt==12)
cout<<" Data-Entry of "<<year<<" is already been done ";
for(i=cnt+1;i<=12;i++)
{
enteragain:
cout<<" Do u wan't to enter data for"<<returnMonth(i)<<" (Y or N) Y : ?";
c=getche();
if(c=='n' || c=='N')
goto endRecord;
obj.getdata(i);
if(obj.validate(obj.returntemp(i)))
{
cout<<" Invalid Data Entry ";
goto enteragain;
}
cin.get(c);
file.write((char *) &obj, sizeof(obj));
}
}
getch();
endRecord:
break;
case '6' : clrscr();
cout<<" *****Change Data***** ";
if(checkFile()){
goto endchange;
}
else{
cnt=file.tellg();
cnt=cnt/sizeof(obj); //cnt contains how many records previously recorded
tryagain:
cout<<" Enter Month (in digit) whose temperature is to be changed : ?";
cin>>m;
if(m <= 0 || m > cnt){
cout<<" Invalid Month ";
getch();
goto tryagain;
}
tempagain:
cout<<" Enter Temperature : ?";
cin>>t;
if(obj.validate(t))
{
cout<<" Invalid Data Entry ";
goto tempagain;
}
file.seekg(0,ios::beg);
location= (m-1) * sizeof(obj);
file.seekp(location);
obj.updatedata(m,t);
cin.get(c);
file.write((char *) &obj, sizeof(obj))<<flush;
}
endchange:
break;
case '7' : clrscr();
cout<<" *****Store the Current Data***** ";
if(checkFile()){
goto endsave;
}
flush(file);
cout<<" Data in Memory is Saved successfully ";
getch();
endsave:
break;
default : cout<<" Invalid Input ";
getch();
}
}
while(choice!='0');
flush(file);
file.close();
clrscr();
out:
}