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");
}
Related
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
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;
}
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
Alrighty, the goal of what I am trying to do right now is call the function getSingleStudentInfo, which contains the student's number, last name, and age. In the end this program is designed to do two things, the first being the single student info, the second, printing out an array of 20 students. Disregard the second part, as I have not really gotten into that part yet, so ignore anything involving vectors.
The problem that I am having is that in main the first thing that the program will do is ask you to press 1 for the single info or 2 for the full 20 peoples info. The program compiles fine, but what happens is, no matter what number you enter, the program will say "process returned 0 (0x0)" and be done, I'm having a hard time figuring out why it is doing that instead of printing out the single students info, being "student's ID number is 400" "student's last name is: Simmons" "student's age is: 20"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Student {
int studentNumber = 400;
string lastName = "Simmons";
int age = 20;
};
Student s;
int selection;
vector<int> studentNumber (20);
vector<string> lastName;
vector<int> age (20);
void getSingleStudentInfo (int studentNumber, string lastName, int age) {
cout << "Student's ID number is: ";
cout << s.studentNumber << endl;
cout << "Student's last name is: ";
cout << s.lastName << endl;
cout << "Student's age is: ";
cout << s.age << endl;
return;
};
int main()
{
cout << "Press '1' to see a single student data entry" << endl;
cout << "Press '2' to see all 20 student records" << endl;
cin >> selection;
if (selection == 1) {
getSingleStudentInfo;
};
/*for (vector<int>::size_type i = 0; i <= 20; i++)
{
cout << "Student's ID number is: " << 400 + i << endl;
}
return 0;*/
}
You need to call the function, e.g.
if (selection == 1)
{
getSingleStudentInfo(7, "Johnson", 20);
}
However, it seems like by the implementation, this should be a method off of the student itself
struct Student {
int studentNumber = 400;
string lastName = "Simmons";
int age = 20;
void getSingleStudentInfo() const;
};
Then you'd call it off a Student instance
Student s{400, "Simmons", 20};
s.getSingleStudentInfo();
Then if you had a vector of Student you could do
std::vector<Student> students; // assume this has been populated
std::for_each(begin(students),
end(students),
[](const Student& s){s.getSingleStudentInfo();});
To print in columns, you could change your function to something like
void Student::getSingleStudentInfo()
{
cout << s.studentNumber << '\t'
<< s.lastName << '\t'
<< s.age << endl;
};
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).