Date Struct is not properly being checked - c++

I have some C++ code:
#include <bjarne/std_lib_facilities.h>
struct Date {
int month;
int day;
int year;
};
Date get_date();
Date get_birth_date();
int days_in_month (int month);
bool is_valid_date (const Date& date);
bool is_before (const Date& date1, const Date& date2);
int main()
{
cout << "Welcome to Age Calculator!\n";
Date current;
current = get_date();
cout << "Would you like to see how old you are (y/n)?";
char answer, slash;
cin >> answer;
Date birthday;
if(answer == 'y'){
birthday = get_birth_date();
bool valid = is_valid_date (birthday);
bool before = is_before (current,birthday);
while(!valid && !before){
cout << "Invalid birth date? Please re-enter: ";
cin >> birthday.month >> slash >> birthday.day >> slash >> birthday.year;
valid = is_valid_date (birthday);
before = is_before (current,birthday);
}
cout << "Your birthday is: " << birthday.month << "/" << birthday.day << "/" << birthday.year << "\n";
}
else
cout << "You are so chicken! \n";
}
Date get_date()
{
cout << "Please enter today's date (mm/dd/yyyy): ";
Date today;
char slash;
cin >> today.month >> slash >> today.day >> slash >> today.year;
bool valid = is_valid_date (today);
while(!valid){
cout << "Invalid date? Please re-enter: ";
cin >> today.month >> slash >> today.day >> slash >> today.year;
valid = is_valid_date (today);
}
cout << "Date entered was: " << today.month << "/" << today.day << "/" << today.year << "\n";
return today;
}
Date get_birth_date()
{
cout << "Please enter your birth date (mm/dd/yyyy): ";
Date birth;
char slash;
cin >> birth.month >> slash >> birth.day >> slash >> birth.year;
return birth;
}
int days_in_month (int month)
{
int month31[7] = {1,3,5,7,8,10,12};
for(int i = 0; i < 7; i++){
if(month == month31[i])
return 31;
}
int month30[4] = {4,6,9,11};
for(int i = 0; i < 4; i++){
if(month == month30[i])
return 30;
}
if(month == 2)
return 28;
}
bool is_valid_date (const Date& date)
{
int months[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
int days = 0;
for(int i = 0; i < 12; i++){
if(date.month == months[i]){
days = days_in_month (date.month);
if(date.day <= days && date.day > 1){
return true;
}
}
return false;
}
bool is_before (const Date& date1, const Date& date2)
{
cout << date1.day << " " << date2.day;
if(date2.year < date1.year){
return true;
}
else if(date2.year == date1.year)
{
cout << "-";
if(date2.month < date1.month)
return true;
else if(date2.month == date1.month){
if(date2.day <= date1.day)
return true;
}
else
return false;
}
return false;
}
I know that the is_valid_date function works, but when I'm testing a birthday that comes after the current day entered, for some reason, it passes the is_before test and never goes to the while loop asking the user to enter a valid birthday. Any suggestions would be greatly appreciated! Thanks in advance!
Edit: The specific inputs that I'm testing are: for today's date, I enter 05/06/2015 and for a birthday, I enter 05/07/2015. It then prints the birthday, which means it skips the while loop in int main(), which it shouldn't do, since the birthday comes after the current date.

Your condition is wrong:
while(!valid && !before)
Your condition tries to get a new birthday if the one entered is invalid and is after the current date. I think you want:
while(!valid || !before)
Which gets a new birthday if the one entered is invalid or is after the current date.

You should change while(!valid && !before) to while(!valid || !before).
You want to stay in the loop as long as the birth date is invalid or the birth date is after the current date. Currently, if you enter a valid date which is after the current date, it will break out of the loop because the first condition is false (the date is valid).

Related

Printing a void c++

To give background on my code. I'm supposed to take the user input, find the month and day they input in the txt file and print that out which sound sooo simple to me but I just can't get my code to work. I want to take that I created and put it in the main so I can print whatever I have cout in that void code. I wanted some guidance to see where exactly I'm going wrong.
int main() {
cout << "please enter month first and then day: ";
cin >> searchMonth;
cin >> searchDay;
if (searchMonth == month && searchDay == day){
for (int i=0; i<TOTALDATA; i++){
infile >> year >> month >> day >> hour >> minute >> latitude >> longitude >> magnitude >> state;
earthquakeData oneEarthquake;
oneEarthquake.yearOfEarthquake = year;
oneEarthquake.monthOfEarthQuake = month;
oneEarthquake.dayOfEarthquake = day;
oneEarthquake.hourOfEarthquake = hour;
oneEarthquake.minOfEarthquake = minute;
oneEarthquake.yearOfEarthquake = latitude;
oneEarthquake.earthquakeLatitude = longitude;
oneEarthquake.earthquakeMagnitude = magnitude;
oneEarthquake.earthquakeState = state;
earthquakes[i] = oneEarthquake;// row i is set to oneEarthquake
earthquakeDetails (earthquakes[i]) ;
}
}
infile.close();
return 0;
}
void earthquakeDetails (earthquakeData earthquakes[TOTALDATA]){
for (int i=0; i<TOTALDATA; i++){
cout << earthquakes[i].yearOfEarthquake;
cout << earthquakes[i].monthOfEarthQuake;
cout << earthquakes[i].dayOfEarthquake;
cout << earthquakes[i].hourOfEarthquake << ":" << earthquakes[i].minOfEarthquake;
cout << earthquakes[i].earthquakeLatitude << earthquakes[i].earthquakeLongitude;
cout << earthquakes[i].earthquakeMagnitude;
cout << earthquakes[i].earthquakeState;
}
}```
Things you are doing wrong:
read from user without checking the input
read from file before opening a file (or your MRE is incomplete)
if outside of loop
if before reading from file
calling looping output function from looping search function

How to make one function's if/else condition control other function in a structure?

We got an assignment where we were supposed to make a birthday wisher. Now whenever the input for month date and year is invalid ( such as negative or zero or beyond the range of months and days) the program should not proceed forth. How to make it do that?
#include <iostream>
using namespace std;
struct birthday_wisher {
int date;
int month;
int year;
int todaysdatedd,todaysdatemm;
void getdob() {
cout << "enter your date of birth (dd/mm/yy) " << endl;
cin >> date >> month >> year;
if ((todaysdatedd > 0 && todaysdatedd <= 31) && (todaysdatemm > 0 && todaysdatemm <= 12) && year>0 )
{
cout << "you have entered a valid date " << endl;
}
else
{
cout << "invalid date/ month\n";
}
}
void gettodaysdate() {
cout << "enter today's date (dd/mm)\n";
cin >> todaysdatedd >> todaysdatemm;
if ((todaysdatedd>0 && todaysdatedd<=31) && (todaysdatemm>0 && todaysdatemm<=12))
{
cout << "you have entered a valid date" << endl;
}
else
{
cout << "invalid date/ month";
}
}
void check() {
if (month == todaysdatemm) {
if (date == todaysdatedd)
{
cout << "happy birthday!";
}
}
else
{
cout << "your birthday is not today ;-;\n";
}
}
};
int main()
{
birthday_wisher b1;
b1.getdob();
b1.gettodaysdate();
b1.check();
}
You got a few options.
The brute option: Put exit(int exitCode) after the check fails. This will immediately exit the program e.g.
if (IsNotAValidDate())
{
exit(1);
}
The better option: Make getdob to return bool and make the program peacefully exit if the condition fails.
bool getdob() {
// You might want to check also for 31/30 day months and for February as here are bugs
cout << "enter your date of birth (dd/mm/yy) " << endl;
cin >> date >> month >> year;
return (todaysdatedd > 0 && todaysdatedd <= 31) && (todaysdatemm > 0 && todaysdatemm <= 12) && year>0;
}
int main()
{
birthday_wisher b1;
if (b1.getdob())
{
b1.gettodaysdate();
b1.check();
}
else
{
std::cout << "Invalid date provided\n";
}
return 0;
}

Why does my code not display updated dates? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Okay so what this program is supposed to do is display the date in M/D/Y format and for some unknown reason it always displays 1/1/1. I have been skimming through this the past 40 mins and still can't understand where I went wrong. Please help me out. Needmorewordstopostthissssssssssssssssssssssssssssssssssssssssssssssss
#include <iostream>
using namespace std;
void displayDate();
class Date{
public:
int month;
int day;
int year;
int mmax;
//functions
int getMonth();
int getDay();
int getYear();
int setMonth();
int setDay();
int setYear();
};
int Date::setMonth(){
int i;
for (i=1; i!=0; i=1)
{
cout << "\n Input the month: ";
cin >> month;
if (month < 1) {
cout << "Please input a valid month";
}
else if (month > 12){
cout << "Please input a valid month";
}
else{
break;
}
}
return month;
}
int Date::setDay(){
int i;
for (i=1; i!=0; i=1)
{
cout << "\n Input the day: ";
cin >> day;
if (day < 1) {
cout << "Please input a valid day";
}
else if ((month == 1 || 3 || 5 || 7 || 8 || 10 || 12) && (day > 31)){
cout << "Please input a valid day";
}
else if ((month == 4 || 6 || 9 || 11) && (day > 30)){
cout << "Please input a valid day";
}
else if ((month == 2) && (day > 28)){
cout << "Please input a valid day";
}
else{
break;
}
}
return day;
}
int Date::setYear(){
int i;
for (i=1; i!=0; i=1)
{
cout << "\n Input the year: ";
cin >> year;
if (year < 1) {
cout << "Please input a valid year";
}
else if (year > 2021){
cout << "Please input a valid year";
}
else{
break;
}
}
return year;
}
int Date::getMonth(){
int month;
return month;
}
int Date::getDay(){
int day;
return day;
}
int Date::getYear(){
int year;
return year;
}
void displayDate(int d,int m, int y){
cout << "Date: " <<m;
cout << "/" <<d;
cout << "/" <<y;
}
main(){
Date x;
int m,d,y;
x.setMonth();
x.setDay();
x.setYear();
m = x.getMonth();
d = x.getDay();
y = x.getYear();
displayDate(d, m ,y);
}
In your code, the getter is not returning the class member variables rather the local variables delared.
int Date::getMonth(){
return month;
}
int Date::getDay(){
return day;
}
int Date::getYear(){
return year;
}
Make the getters like this to return the actual member value.
int Date::getYear(){
int year;
return year;
}
In here, you declare a new int year; variable, that is not initialized, then you return that variable instead of the member variable of your class.
Change it to
int Date::getYear(){
return year;
}
Similar for your other get() functions.
Your conditions are also not working as you want it to:
(month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
doesn't compare month to all those numbers, the numbers just all evaluate to true. The condtion should be:
(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
I have tried to fix a number of problems in your code. And I have added comments explaining why:
#include <iostream>
// using namespace std; // avoid it if you can. It brings too many symbol in main workspace
using std::cout;
using std::cin;
void displayDate();
class Date{
private: // attributes should be private, only accessors should be public (encapsulation)
int month;
int day;
int year;
//int mmax; // comment out member that the code does not (still) use
//functions
public:
int getMonth();
int getDay();
int getYear();
int readMonth(); // setMonth should be a setter: int setMonth(int month) { this->month = month;}
int readDay();
int readYear();
};
int Date::readMonth(){
for (;;) // idiomatic form for an endless loop
{
cout << "\n Input the month: ";
cin >> month;
if (month < 1) {
cout << "Please input a valid month";
}
else if (month > 12){
cout << "Please input a valid month";
}
else{
break;
}
}
return month;
}
int Date::readDay(){
for (;;)
{
cout << "\n Input the day: ";
cin >> day;
if (day < 1) {
cout << "Please input a valid day";
}
else if (day > 31){ // other conditions were useless
cout << "Please input a valid day";
}
else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day > 30)){ // fix
cout << "Please input a valid day";
}
else if ((month == 2) && (day > 28)){
cout << "Please input a valid day";
}
else{
break;
}
}
return day;
}
int Date::readYear(){
for (;;)
{
cout << "\n Input the year: ";
cin >> year;
if (year < 1) {
cout << "Please input a valid year";
}
else if (year > 2021){
cout << "Please input a valid year";
}
else{
break;
}
}
return year;
}
int Date::getMonth(){
//int month; // the local variable would hide the member
return month;
}
int Date::getDay(){
//int day;
return day;
}
int Date::getYear(){
//int year;
return year;
}
void displayDate(int d,int m, int y){
cout << "Date: " <<m;
cout << "/" <<d;
cout << "/" <<y;
cout << '\n'; // do not forget end of lines
}
int main(){ // main shall be declared to return int
Date x;
int m,d,y;
x.readMonth();
x.readDay();
x.readYear();
m = x.getMonth();
d = x.getDay();
y = x.getYear();
displayDate(d, m ,y);
return 0; // better to be explicit
}
Other things could be improved, because re-usability is important in OOP. But I am too lazy to go further today ;-)

What should I change or delete in order to fix this code so the rest may work fine?

#include <h1>iostream <h2>
#include <h1>cmath<h2>// for + of months, days, and years
#include <h1>fstream<h2> //for in and output
#include <h1>cstdlib<h2>
#include <h1>string<h2>//for string type
using namespace std;
class Device {//Input and store Device Description and Serial Numbers
protected:
string serial_number;
string device_description;
public:
Device() {
serial_number = ("6DCMQ32");
device_description = ("TheDell");
}
Device(string s, string d) {
serial_number = s;
device_description = d;
}
};
class Test {
protected:
string Test_Description;
static int recent_month, recent_day, recent_year, new_month;
static int nmonth, next_month, next_day, next_year, max_day;
public:
static void getMonth() {//Calculates the next/new month
next_month = recent_month + nmonth;
new_month = next_month % 12;
if (next_month >= 12) {
cout << "The next Date: " << new_month << " / ";
}
else {
cout << "The next Date: " << next_month << " / ";
}
}
static void getDay() { //Calculates day of next month
if (new_month == 4 || new_month == 6 || new_month == 9 || new_month == 11) {
max_day = 30;
}
else if (new_month == 2) {
max_day = 29;
}
else {
max_day = 31;
}
if (recent_day > max_day) {
cout << max_day << " / ";
}
else {
cout << recent_day << " / ";
}
}
static void getYear() {//Calculates the year of the next number of months
next_year = recent_year + next_month;
if (next_year >= 12) {
cout << recent_year + (next_month / 12) << endl;
}
else {
cout << next_year << endl;
}
}
static void getDate() {
Test::getMonth(), Test::getDay(), Test::getYear();
}
};
int Test::recent_month, Test::recent_day, Test::recent_year,
Test::new_month;
int Test::nmonth, Test::next_month, Test::next_day, Test::next_year,
Test::max_day;
class Lab : public Device, public Test {//Class Lab is a Child of Class Test and Class Device
protected:
static int n;
public:
friend istream & operator>>(istream & cin, const Lab & lab) {
cout << "Enter Device Description and serial number: ";
getline(cin, lab.device_description);//This is where the error is
getline(cin, lab.serial_number);//This is where the error is
cout << "Enter Test Description: ";
getline(cin, lab.Test_Description);//This is where the error is
cout << "Enter number of months: ";
cin >> lab.nmonth;
cout << "Enter the most recent date(mm/dd/yyyy): ";
cin >> lab.recent_month >> lab.recent_day >> lab.recent_year;
return cin;
}
friend ostream & operator<<(ostream & cout, const Lab & lab) {
cout << lab.device_description << " ";
cout << lab.serial_number << endl;
cout << lab.Test_Description << endl;
getDate();
return cout;
}
static void getFile() {
cout << "Enter the number of devices: ";
cin >> n;
Lab *obj = new Lab[n];
if (obj == 0) {
cout << "Memory Error";
exit(1);
}
for (int i = 0; i<n; i++) {
cin >> obj[i];
}
ofstream myfile("Device.dat", ios::binary);
myfile.write((char *)obj, n * sizeof(Lab));
Lab *obj2 = new Lab[n];
ifstream file2("Device.dat", ios::binary);
if (obj2 == 0) {
cout << "Memory Error";
exit(1);
}
file2.read((char *)obj2, n * sizeof(Lab));
for (int i = 0; i < n; i++) {
cout << obj2[i];
cout << endl;
}
delete[] obj2;
}
void getSearch(){
}
};
void main() {
Lab L;
L.getFile();
system("pause");
}
//Error C2665 'std::getline': none of the 2 overloads could convert all
the argument types
/*
Purpose: is to enter the number of months for the next test date of device with input of serial number, Device Description, Test Description, recent date, and the number of months of two tests. At the end the program must be searched by having the user to input the serial number and the next date, if these two are valid everything in the device is listed out.
*/<
You shouldn't name your parameters like objects of the standard library (cin).
For an argument to be modifiable it must not be a reference to a constant entity.
Also, a std::istream bound operator<<() overload should not do output, but only extract the object required from the stream.

I don't understand why this code isn't performing properly

/* Program Name: BadDate.cpp
Function: This program determines if a date entered by the user is valid.
Input: Interactive
Output: Valid date is printed or user is alerted that an invalid date was entered
*/
#include <iostream>
bool validateDate(int, int, int);
using namespace std;
int main()
{
// Declare variables
int year;
int month;
int day;
const int MIN_YEAR = 0, MIN_MONTH = 1, MAX_MONTH = 12, MIN_DAY = 1, MAX_DAY = 31;
bool validDate = true;
This is the work of the housekeeping() method
Get the year, then the month, then the day
int housekeeping() {
cout << "Please enter a year: "<< endl;
cin >> year;
cout << "Please enter a month: "<< endl;
cin >> month;
cout << "Please enter a day: "<< endl;
cin >> day;
}
This is the work of the detailLoop() method
Check to be sure date is valid
int detailLoop() {
if(year <= MIN_YEAR) // invalid year
validDate = false;
else if (month < MIN_MONTH || month > MAX_MONTH) // invalid month
validDate = false;
else if (day < MIN_DAY || day > MAX_DAY) // invalid day
validDate = false;
}
This is the work of the endOfJob() method
test to see if date is valid and output date and whether it is valid or not
int endOfJob()
{
if(validDate == true)
{
// Output statement
cout << " Your date is valid!"<< endl;
}
else
{
// Output statement
cout << " Your date is not valid!"<< endl;
}
}
} // end of main() function