Restart loop in a parallel array - c++

For my assignment, I cannot allow a user to enter a negative value for rainfall in the array. I'm suppose to restart the loop over again as if they didn't enter anything to start off with and have them try again.
When I try it, I enter a negative value the first time, it restarts it for January, but after that I can enter more negatives and it just keeps asking me to keep entering for the rest of the months. I want it to keep restarting if I keep giving it negative numbers, until I start entering positive numbers. Then, that's when I display the total and average.
{
const int SIZE = 12;
string months[SIZE] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
string Month[SIZE];
double Rainfall[SIZE];
int counter;
double totalRainfall = 0.0;
double averageRainfall = 0.0;
for (counter = 0; counter < SIZE; counter++)
{
cout << "Enter the total rainfall for " << months[counter] << ": ";
cin >> Rainfall[counter];
if (Rainfall[counter] < 0.0)
{
cout << "Sorry, can't be a negative!" << endl;
do
{
for (counter = 0; counter < SIZE; counter++)
{
cout << "Enter the total rainfall for " << months[counter] << ": ";
cin >> Rainfall[counter];
}
} while (Rainfall[counter] < 0.0);
}
averageRainfall = totalRainfall / SIZE;
cout << "Total rainfall for the whole year was: " << totalRainfall << setprecision(3) << endl;
cout << "The average inches of rainfall was: " << averageRainfall << setprecision(3) << endl;
system("pause");
return 0;
}
}

Here is a basic working example to what you are trying to accomplish. Rather than adding and then checking, I checked first before I add the value into the array. I created a simple function to make sure that the input is a valid number. If its not, simply reset the counter back to 0 and the for loop will start from the beginning.
Edit: add a try and catch block to make sure input is a proper double
#include <iostream>
#include <string>
bool is_valid_num(std::string str){
//check if its a number
for(char c : str){
if((c < 48 || c > 57 ) && c != 46) return false;
}
//if you want it to also not be equal to 0
// if(std::stoi(str) < 0) return false;
return true;
}
int main() {
const int SIZE = 12;
std::string months[] = { "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" };
std::string temp_input;
double rainfall[12];
double total_rainfall = 0.0;
for(int i = 0; i < SIZE; i++){
std::cout << "enter rainfall for " << months[i] << ": ";
std::cin >> temp_input;
//restart back to january
if(!(is_valid_num(temp_input))) i = -1;
rainfall[i] = std::stod(temp_input);
total_rainfall += std::stod(temp_input);
}
std::cout << "avg rainfall: " << total_rainfall / 12.0 << "\n";
std::cout << "total rainfall " << total_rainfall << "\n";
}

Well that's your while loop where you are stuck, when second time you put negative values you are already in while loop so it wont print sorry.... rather it will restart while loop from counter = 0,
rather do this
if (Rainfall[counter] < 0.0)
{
cout << "Sorry, can't be a negative!" << endl;
counter--;// either put zero if you want to restart whole loop else decrement
continue;
}

Related

How do I pass my arrays to my other functions?

So I am having a problem with passing my arrays to my functions and I cant seem to get it to work
I have this so far...
int getProfit();
int getTotal();
int main(){
int profits[12];
string monthNames[12] = {"January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
int quarterProfits[4];
cout << "Welcome to my comic store!\n" << endl;
getProfit();
getTotal();
}
int getProfit(){
for(int i = 0; i < 12; i++){
cout << "Enter the profit for month " << i + 1 << ": " << endl;
cin >> profits[i];
if(profits[i] < 0){
cout << "Invalid profit! Please enter the profit for month " << i + 1 << ": "<< endl;
cin >> profits[i];
}
}
}
int getTotal(){
int profitTotal = 0;
for(int i = 0; i < 12; i++){
profitTotal = profitTotal + profits[i];
}
return profitTotal;
}
So right now I am trying to pass my profits array to my getTotal function but nothing I try seems to work.
I think the problem may be that I am getting my profits array from another function (getProfit), but i'm not sure.
Any improvements or suggestions are welcome. Thanks!
The problem is that you are not declaring profits as a parameter, a function does not know about its environment only about its parameters and what it is supposed to do, so, you have to send the array as a parameter
/*
call it in the main function as
getProfit(profits); (don't forget modify the prototype)
Note: do it same in getTotal
*/
int getProfit(int *profits) {
for(int i = 0; i < 12; i++) {
cout << "Enter the profit for month " << i + 1 << ": " << endl;
cin >> profits[i];
while (profits[i] < 0) {//if only checks once
cout << "Invalid profit! Please enter the profit for month " << i + 1 << ": ";
cin >> profits[i];
}
}
}
See this page for further information about pointers and arrays

How to do a input validation with a string of array?

I'm writing a program where I have to input a month which follows with an output of how many days are in that month. However, I also have to write a code where if the input is not a valid month, it shows an error message. I haven't been able to figure out how to output that error statement. I already figured out the rest though.
I have tried the while loop, but it has not worked for me. I know I must be doing something wrong, but I don't know how to fix it.
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int MONTHS = 12;
int days[MONTHS] = { 31, 28, 31, 30,
31, 30, 31, 31,
30, 31, 30, 31 };
string m;
string i[MONTHS] = { "January", "February", "March",
"April", "May", "June", "July",
"August", "September", "October",
"November", "December" };
cout << "Enter the name of the month: " << endl;
cin >> m;
while (m < MONTHS)
{
cout << "Invalid month entered! Exit the program to try again."
<< endl;
}
cout << endl;
for (int count = 0; count < MONTHS; count++)
if (m == i[count])
{
cout << "There are " << days[count] << " days in "
<< i[count] << "." << endl;
}
return 0;
}
This is the expected result whenever the user inputs a invalid month.
Input the name of a month: Orion
Orion is not the name of a month.
Your while loop is trying to compare m (a string) with MONTHS (the integer 12). Rather than try to fix that, my suggestion is to adjust the code following your for loop. You're already comparing m to each month in the array, right? If m matches, there's no need to continue looping, so you can simply return at that point. Then, if the for loop completes without a match, you know the month was invalid and can report it. Something like this:
for (int count = 0; count < MONTHS; count++)
if (m == i[count])
{
cout << "There are " << days[count] << " days in "
<< i[count] << "." << endl;
return 0;
}
cout << m " is not the name of a month." << endl;
return 1;
There are a couple of little problems contributing to your error.
The first is that you are comparing string m to int MONTHS. That won't work (possibly at all, but at the very least) the way you expect it.
Second, as others have mentioned, there is nothing inside your loop to end the loop. You will want to reset the value of m that way you don't get an infinite loop.
Here is a suggestion of something you could do that should work as you want it to:
NOTE: it requires an std::map
#include <iostream>
#include <string>
#include <map> // if you wanted to do it this way
using namespace std;
int main()
{
const int MONTHS = 12;
int days[MONTHS] = { 31, 28, 31, 30,
31, 30, 31, 31,
30, 31, 30, 31 };
string m;
map<string, int> i = { ("January", 0}, "February", 1}, "March", 2},
{"April", 3}, {"May", 4}, {"June", 5}, {"July", 6},
{"August, 7}", {"September, 8}", {"October, 9}",
{"November, 10}", {"December, 11}" };
cout << "Enter the name of the month: " << endl;
cin >> m;
while (m.find(m) == m.end())
{
cout << "Invalid month entered! Exit the program to try again."
<< endl;
cout << "Enter the name of the month: " << endl;
cin >> m;
}
cout << endl;
cout << "There are " << days[i[m]] << " days in "
<< m << "." << endl;
return 0;
}
I guess this is an assignment? For the main function you could use a map.
Here are some hints so you can complete the task.
Also remember that string comparison is case sensitive which needs to be addressed.
#include <stdio.h>
#include <string>
#include <map>
struct comparer
{
public:
bool operator()(const std::string x, const std::string y) const
{
return x.compare(y)==0;
}
};
int main()
{
map<string, int> months;
months.insert(pair<string, int>("january", 31));
months.insert(pair<string, int>("february", 28));
months.insert(pair<string, int>("mars", 31));
months.insert(pair<string, int>("april", 30));
cout << "Enter the name of the month: " << endl;
cin >> m;
std::map<std::string, int, comparer>::iterator it=months.find(m);
if(it!=months.end())
printf("The number of days is %d\n",(*it).second);
else
printf("Error, the month not found\n");
}

Print out dates in four formats

I need to print out dates in four formats when a user enters a month, day and year.
For example if I enter "sept" for month, 17 for day and 1921 for year, it will print out:
1) 9/17/1921
2) September 17,1921
3) 1921-9-17
4) 1921-sep-17
I also do validation where if the number of days is less than 1 or greater than than the number of days for that month and the year cannot be less than 1900 or greater than 2020. If it is, month gets defaulted to "January" day to 1 and year to 2001.
When I enter jan for month 5 for day 2005 for year, I get weird values in my console 1/-858993460/-858993460 and then terminates. But when I enter mar 5 2005 i get
3/5/2005
March2005
ory corruption5
ory corruptionmar-5
I create an instance of Date and call a 3 argument constructor. The 3 argument constructor then calls a validate function which return a boolean. If the return value is false, it will call the default constructor which sets everything to january 1 2001.
//UPDATE:
Changed inital value of int index in date.cpp to -1 instead of NULL. Doing this now calls the print function four times four when I enter "jan" but I still get the weird results
1/5/2005
January2005 //This should be January 5, 2005
ory corruption5
ory corruptionmar-5
Why does the first time print is called all my member variables retain the values, but the 2nd, 3rd, and 4th time, day is missing and shows weird corruption message?
I don't know what is going on but when I also enter an invalid date such as "jan" for month but 36 for days and 2025 for year, the default constructor should set month to January, day to 1 and year to 2001 but I get garbage values
1/-858993460/-858993460
This is the first time print is called then after that it terminates.
//Header
#pragma once
#include <iostream>
#include <string>
using namespace std;
/*Add more constants if needed*/
#ifndef DATE_H
#define DATE_H
enum DateFormat { mdy1, mdy2, ymd1, ymd2 };
const int MIN_YEAR = 1900;
const int MAX_YEAR = 2020;
const string monthStr[] = //alternative: const char monthStr[] [15]=
{ "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November",
"December" };
const string monthStrAbbrev[] = //not strictly necessary, but helpful
{ "jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov",
"dec" };
const int monthDays[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
class Date {
private:
string month;
int day, year;
bool validateDate(string, int, int);
Date();
public:
Date(string, int, int);
void print(DateFormat type);
};
#endif // !DATES_H
//Dates.cpp
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include "date.h"
using std::cout;
using std::cin;
int global;
Date::Date() : month("January"), day(1), year(2001) { cout << "INSIDE CONST" << endl; }
Date::Date(string m, int d, int y)
{
if (!validateDate(m, d, y))
{
cout << "IF FALSE" << endl;
Date();
}
else
{
month = m;
day = d;
year = y;
cout << "MONTH IS :" << month << " DAY IS: " << day << " YEAR IS: " << year << endl;
}
}
bool Date::validateDate(string m, int d, int y)
{
cout << "size is " << sizeof(monthStrAbbrev) / sizeof(monthStrAbbrev[0]) << endl;;
int index = -1;
for (int x = 0; x < 11; x++)
{
string mAbr = monthStr[x].substr (0, 3);
transform(mAbr.begin(), mAbr.end(), mAbr.begin(), (int(*) (int)) tolower);
cout << "Abbr: " << mAbr << endl;
if (m == mAbr)
{
index = x;
global = x;
cout << "x " << x << " global " << global << " Index " << index << endl;
if (d < 1 && d > monthDays[index])
{
cout << "FALSE 1" << endl;
return false;
}
if (y < MIN_YEAR || y > MAX_YEAR)
{
cout << "FALSE 2" << endl;
return false;
}
break;
}
}
if (index == -1)
{
cout << "IF NULL" << endl;
return false;
}
else
{
cout << " IF NOT NULL" << endl;
return true;
}
}
void Date::print(DateFormat type)
{
if (type == mdy1)
{
cout << global + 1 << "/" << day << "/" << year << endl;
}
else if (type == mdy2)
{
cout << monthStr[global] << day + ", " << year << endl;
}
else if (type == ymd1)
{
cout << year + "-" << (global + 1) + "-" << day << endl;
}
else if (type == ymd2)
{
cout << year + "-" << month + "-" << day << endl;
}
}
//Test.cpp
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
#include "date.h"
void setDateValues(string&, int&, int&);
int main()
{
string mth;
int day, yr;
setDateValues(mth, day, yr);
transform(mth.begin(), mth.end(), mth.begin(), (int(*) (int)) tolower);
Date d1(mth, day, yr);
cout << "Date is:\n";
DateFormat type;
type = mdy1;
d1.print(type);
type = mdy2;
d1.print(type);
type = ymd1;
d1.print(type);
type = ymd2;
d1.print(type);
return 0;
}
void setDateValues(string & m, int& d, int& y)
{
cout << "Enter month: ";
cin >> m;
cout << "Enter day: ";
cin >> d;
cout << "Enter year: ";
cin >> y;
}
There is a standard library function for this: strftime().
You give it a date in a struct, and it writes a string. For your four cases, the format strings would be:
1) %m/%d/%Y
2) %B %d, %Y
3) %F
4) %Y-%b-%d

C++ Need help for a homework program that reads in a list of doubles from a file and add a string to each double

I'm having trouble with this homework program and now I'm stuck in what I should do. The program reads in a list of 12 doubles from a file. Each double represents the total rainfall in inches for the 12 months of the year in month order. The 12 doubles should be written into an array. The requirements are below.
This is the code that I have right now and I'm have no idea on what needs to go into the Function declarations displayRainfall, bubbleSort, and swap and what else needs to go into main:
// Headers
#include <iostream> // cout, cin
#include <cstdlib> // exit()
#include <string> // strings
#include <fstream> // file processing
#include <iomanip> // stream manipulation
using namespace std;
// Global variables
const int MAX_MONTHS = 12; // months for rainfall
const string FILENAME = "TotalMonthlyRainfall2014.txt"; // The name of the file that is read
// Function declarations
int loadMonthlyRainfall (double rain[MAX_MONTHS], string fileName, int maxMonths);
void displayRainfall(string months[MAX_MONTHS], double rain[MAX_MONTHS], int monthCount);
void bubbleSort(double rain[MAX_MONTHS], int size);
void swap(int& a, int& b);
int main()
{
int monthCount = 0;
string months[MAX_MONTHS] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
double rain[MAX_MONTHS];
loadMonthlyRainfall(rain, FILENAME, MAX_MONTHS);
// Make sure we place the end message on a new line
cout << endl;
// The following is system dependent. It will only work on Windows
system("PAUSE");
return 0;
}
int loadMonthlyRainfall(double rain[MAX_MONTHS], string fileName, int maxMonths)
{
ifstream inFile; // Input file stream
int numMonths = 0;
// Open file
inFile.open(fileName);
if (!inFile)
{
throw "Can not open file";
}
//
for (int r = 0; r < MAX_MONTHS; r++)
{
inFile >> rain[r];
}
// Close the file
inFile.close();
for (int r = 0; r < MAX_MONTHS; r++)
{
cout << rain[r] << " ";
}
cout << endl;
return numMonths;
}
void displayRainfall(string months[MAX_MONTHS], double rain[MAX_MONTHS], int monthCount)
{
}
void bubbleSort(double rain[MAX_MONTHS], int size)
{
}
void swap(int& a, int& b)
{
}
The program should do the following with the data:
Calculate the average rainfall for the year.
Determine which month had the lowest amount of rainfall.
Determine which month had the highest amount of rainfall.
Sort the array of rainfall in descending order (highest rainfall first) using a bubble sort.
Neatly display the average, minimum, and maximum rainfall. Be sure to display the month of the minimum and maximum rainfalls. Then display a table of month and rainfall amount from the sort.
Each of the monthly rainfall, average, minimum, and maximum
rainfalls should be displayed to two decimal places.
The output should look something like this:
Monthly Rainfall for 2014
Minimum: September 0.06
Maximum: August 4.34
Monthly Average for Year: 1.77
Sorted by Total Rainfall
Month Inches
August 4.34
May 3.40
June 3.26
November 2.13
October 2.09
April 1.74
March 1.45
December 1.13
July 0.98
February 0.41
January 0.33
September 0.06
Call bubbleSort(rain, MAX_MONTHS); in main with these changes :
void displayRainfall(string months[MAX_MONTHS], double rain[MAX_MONTHS], int monthCount)
{
//title
cout << "Monthly Rainfall for 2014" << endl;
//print minimum rainfall
cout << "Minimum: " << months[MAX_MONTHS-1] << " "<< rain[MAX_MONTHS-1] << endl;
//print maximum rainfall
cout << "Maximum: " << months[0] << " "<< rain[0] << endl;
//get and print average rainfall
double avg = 0.0;
for (int i = 0; i < MAX_MONTHS; i++)
{
avg+=rain[i];
}
avg = avg/MAX_MONTHS;
cout << "Monthly Average for Year: " << avg << endl;
//print ordered rainfall by month
cout << "Sorted by Total Rainfall" << endl;
cout << "Month" << setw(10) << "Inches" << setw(10) << endl;
for (int i = 0; i < MAX_MONTHS; i++)
{
cout << setw(10) <<months[i] << setw(10) << rain[i] << endl;
}
}
void bubbleSort(double rain[MAX_MONTHS], int size)
{
string months[MAX_MONTHS] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
//sort rainfall descending
for (int i = 1; i < size; i++)
{
for (int j = 0; j < size - i; j++)
{
if (rain[j] < rain[j+1])
{
swap(rain[j], rain[j+1]);
swap(months[j], months[j+1]);
}
}
}
//called inside bubbleSort because months and rain are sorted in scope
displayRainfall(months, rain, 0);
}
void swap(int& a, int& b)
{
int& temp = a;
a = b;
b = temp;
}

Can I compare a char* (month) with a string (February)? If not, how can I go about doing this?

I want the program to work so that I can turn any worded month to its equivalent number.
#include <iostream>
using namespace std;
int main()
{
char month[20];
int INT_month;
cout << "Enter a month: (ex. January, February)";
cin >> month; // Let's say the input is February
if (month == "February")
INT_month = 2;
cout << "The month in its' integral form is " << INT_month << endl;
// INT_month = 2130567168 // WHY DOES IT DO THIS????
return 0;
}
One way to do it is creating a vector of month names, and using the look-up index plus one as the month number:
vector<string> months = {
"january", "february", "march", ...
};
string search = "march";
auto pos = find(months.begin(), months.end(), search);
if (pos != months.end()) {
cout << "Month number: " << distance(months.begin(), pos) + 1 << endl;
} else {
cerr << "Not found" << endl;
}
This prints 3 (demo on ideone).