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
Related
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");
}
I have been trying to figure out how to accurately subtract one date from another in C++. Both will be received through user input. I thought that by creating a class, along with the use of <ctime>, I would be able to do this but I have yet to find how to do so while taking Leap years into consideration, which would be the cause for the loss of accuracy that it might have.
Here is how I was approaching the task:
#include "pch.h"
#include <iostream>
#include <ctime>
using namespace std;
class Year {
private:
struct tm date3;
struct tm date2;
struct tm date;
int FirstYear, SecondYear;
int FirstMonth, SecondMonth;
int FirstDay, SecondDay;
public:
int DateCalculus(struct tm* date, struct tm* date2);
void ResultShown();
};
int Year::DateCalculus(struct tm* date, struct tm* date2) {
struct tm date3;
date3.tm_year = date->tm_year - date2->tm_year;
date3.tm_mon = date->tm_mon - date2->tm_mon;
date3.tm_mday = date->tm_mday - date2->tm_mday;
}
void Year::ResultShown() {
cout<< date3;
}
int main() {
struct tm Date = { 0, 0, 12 };
struct tm Date2 = { 0, 0, 12 };
int Firstyear, SecondYear;
int Firstmonth, SecondMonth;
int Firstday, SecondDay;
cin >> Firstday; cout << "Day 1 " << endl;
cin >> Firstmonth; cout << "Month 1 " << endl;
cin >> Firstyear; cout << "Year 1 " << endl;
cin >> SecondDay; cout << "Day 2 " << endl;
cin >> SecondMonth; cout << "Month 2 " << endl;
cin >> SecondYear; cout << "Year 2 " << endl;
Date.tm_year = Firstyear;
Date.tm_mon = Firstmonth;
Date.tm_mday = Firstday;
Year::DateCalculus(&Date, &Date2);
cout << asctime(&Date2) << std::endl;
return 0;
}
I'm writing a program that converts a short date (mm/dd/yyyy) to a long date (March 12, 2014) and prints out the date.
The program has to work given the following user inputs:
10/23/2014
9/25/2014
12/8/2015
1/1/2016
I have the program working with the first user input but I'm not sure how to proceed with handling a user input that doesn't have a "0" in the first position of the string.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string date;
cout << "Enter a date (mm/dd/yyyy): " << endl;
getline(cin, date);
string month, day, year;
// Extract month, day, and year from date
month = date.substr(0, 2);
day = date.substr(3, 2);
year = date.substr(6, 4);
// Check what month it is
if (month == "01") {
month = "January";
}
else if (month == "02") {
month = "February";
}
else if (month == "03") {
month = "March";
}
else if (month == "04") {
month = "April";
}
else if (month == "05") {
month = "May";
}
else if (month == "06") {
month = "June";
}
else if (month == "07") {
month = "July";
}
else if (month == "08") {
month = "August";
}
else if (month == "09") {
month = "September";
}
else if (month == "10") {
month = "October";
}
else if (month == "11") {
month = "November";
}
else {
month = "December";
}
// Print the date
cout << month << " " << day << "," << year << endl;
return 0;
}
I'd greatly appreciate any help.
As Red Serpent wrote in the comments: Search for the / using std::string::find, e.g.
#include <iostream>
int main()
{
std::string date = "09/28/1983";
int startIndex = 0;
int endIndex = date.find('/');
std::string month = date.substr(startIndex, endIndex);
startIndex = endIndex + 1;
endIndex = date.find('/', endIndex + 1);
std::string day = date.substr(startIndex, endIndex - startIndex);
std::string year = date.substr(endIndex + 1, 4);
std::cout << month.c_str() << " " << day.c_str() << "," << year.c_str() << std::endl;
return 0;
}
You could also take advantage of stream conversion, for a less efficient but simpler solution:
#include <iostream>
#include <string>
using namespace std;
int main() {
string months[] = {"", "January", "February", "Mars", "April", "May", "June", "Jully", "August", "September", "October", "December"};
cout << "Enter a date (mm/dd/yyyy): " << endl;
char c;
int day, month, year;
cin >> day >> c >> month >> c >> year;
// error handling is left as an exercice to the reader.
cout << months[month] << " " << day << ", " << year << endl;
return 0;
}
Hello I am new to C++ expecialy dates in C++.. how can I compare these numbers 29(day) 08(month) 86(year) with todays date to get age ?
Here is hwo I started my function:
std::string CodeP, day, month, year, age;
std::cout<<"Enter Permanent Code(example: SALA86082914) :\n "; //birthday first six numbers in code
std::cin>>CodeP;
year = CodeP.substr (4,2);
month = CodeP.substr (6,2);
day = CodeP.substr (8,2);
std::cout<<"day :"<<day <<'\n';
std::cout<<"month :"<<month <<'\n';
std::cout<<"year :"<<year <<'\n';
//then get today's date to compare with the numbers of birthday to get age
First subtract the years to get the difference. Now compare the months; if today's month is greater than the birth month, you're done. If not, compare the days; if today's day is greater than the birth day, you're done. Otherwise subtract one from the difference and that's the age.
Try my code below, I already did the necessary code for the comparing and the processing of two dates that you will be needing. Take note that my code's role is just to compare two dates and give the resulting age based from those dates.
Sorry but I have to leave you the job of creating a code that will give you your expected output based from a six-digit birthday input. I guess you already know that you still have to come up with your own solution for your problem, we are only here to give you an idea on how you can tackle it. We could only do so much to help and support you. Hope my post was helpful!
class age
{
private:
int day;
int month;
int year;
public:
age():day(1), month(1), year(1)
{}
void get()
{
cout<<endl;
cout<<"enter the day(dd):";
cin>>day;
cout<<"enter the month(mm):";
cin>>month;
cout<<"enter the year(yyyy):";
cin>>year;
cout<<endl;
}
void print(age a1, age a2)
{
if(a1.day>a2.day && a1.month>a2.month)
{
cout<<"your age is DD-MM-YYYY"<<endl;
cout<<"\t\t"<<a1.day-a2.day<<"-"<<a1.month-a2.month<<"-"<<a1.year-a2.year;
cout<<endl<<endl;
}
else if(a1.day<a2.day && a1.month>a2.month)
{
cout<<"your age is DD-MM-YYYY"<<endl;
cout<<"\t\t"<<(a1.day+30)-a2.day<<"-"<<(a1.month-1)-a2.month<<"-"<<a1.year-a2.year;?
cout<<endl<<endl;
}
else if(a1.day>a2.day && a1.month<a2.month)
{
cout<<"your age is DD-MM-YYYY"<<endl;
cout<<"\t\t"<<a1.day-a2.day<<"-"<<(a1.month+12)-a2.month<<"-"<<(a1.year-1)-a2.year;
cout<<endl<<endl;
}
else if(a1.day<a2.day && a1.month<a2.month)
{
cout<<"your age is DD-MM-YYYY"<<endl;
cout<<"\t\t"<<(a1.day+30)-a2.day<<"-"<<(a1.month+11)-a2.month<<"-"<<(a1.year-1)-a2.year;
cout<<endl<<endl;
}
}
};
int main()
{
age a1, a2, a3;
cout<<"\t Enter the current date.";
cout<<endl<<endl;
a1.get();
cout<<"\t enter Date of Birth.";
cout<<endl<<endl;
a2.get();
a3.print(a1,a2);
return 0;
}
this will calculate an aproximate of the age(years):
#include <ctime>
#include <iostream>
using namespace std;
int main(){
struct tm date = {0};
int day, month, year;
cout<<"Year: ";
cin>>year;
cout<<"Month: ";
cin>>month;
cout<<"Day: ";
cin>>day;
date.tm_year = year-1900;
date.tm_mon = month-1;
date.tm_mday = day;
time_t normal = mktime(&date);
time_t current;
time(¤t);
long d = (difftime(current, normal) + 86400L/2) / 86400L;
cout<<"You have~: "<<d/365.0<<" years.\n";
return (0);
}
The best way to do that is using Boost.Gregorian:
Assuming
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
You would do:
date bday { from_undelimited_string(std::string("19")+a.substr(4,6)) };
date now = day_clock::local_day();
unsigned years = 0;
year_iterator y { bday };
while( *++y <= *year_iterator(now) )
++years;
--y;
std::cout << *y << "\n";
unsigned months = 0;
month_iterator m { *y };
while( *++m <= *month_iterator(now) )
++months;
--m;
std::cout << *m << "\n";
unsigned days = 0;
day_iterator d { *m };
while( *++d <= *day_iterator(now) )
++days;
--d;
std::cout << *d << "\n";
std::cout << years << " years, " << months << " months, " << days << " days\n";
I found another (simpler?) answer, using Boost.Gregorian
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
template<typename Iterator, typename Date>
struct date_count : public std::pair<unsigned, Date> {
typedef std::pair<unsigned, Date> p;
operator unsigned() { return p::first; }
operator Date() { return p::second; }
date_count(Date begin, Date end) : p(0, begin) {
Iterator b { begin };
while( *++b <= end )
++p::first;
p::second = *--b;
}
};
And you just have to use it this way:
date bday { from_undelimited_string(std::string("19")+a.substr(4,6)) };
date now = day_clock::local_day();
date_count<year_iterator, date> years { bday, now };
date_count<month_iterator, date> months { years, now };
date_count<day_iterator, date> days { months, now };
std::cout << "From " << bday << " to " << now << " there are " <<
std::setw(5) << years << " years, " <<
std::setw(3) << months << " months, " <<
std::setw(3) << days << " days\n";
If you just want the number of years, you can do:
date_count<year_iterator> years(bday, now);
and run with the number of years in the "years" variable. :D
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).