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

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 ;-)

Related

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;
}

Testing a class using for loop in int main

In my main I have to test the class i made with a for loop but am a little stuck. I have to loop through 3 times and get user input for the ticketing system. I tried making an array and storing the user input but nothing I have tried so far has worked. Im trying to call upon the SetWorkTicket with my loop.
#include<iostream>
#include<iomanip>
#include<stdexcept>
#include<sstream>
using namespace std;
// start of the WorkTicket class
class WorkTicket{
public:
// defailt constructors, if the parameters are not specified the ticket will be set to 0 and the date to 1/1/2000. The rest empty strings
WorkTicket() : myTicketNumber(0), myClientId(""), myDay (1), myMonth (1), myYear(2000), myDescription ("") { }
WorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description);
// mutator method that sets all attributes of the object to the parameters as long as valid. If no problems are being detected set TRUE if not then FALSE.....
bool SetWorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description);
// accessor method that will show all the attributes of the ticket in the console menu
void ShowWorkTicket() const;
// here are the sets and gets for the attributes
// ticket number
void SetTicketNumber(int ticketNumber);
int GetTicketNumber() const {return myTicketNumber;}
// client id
void SetClientId(string clientId) {myClientId = clientId;}
string GetClientId() const { return myClientId;}
// date by day
void SetDay(int day);
int GetDay() const { return myDay; }
// date by month
void SetMonth(int month);
int GetMonth() const { return myMonth; }
// date by year
void SetYear(int year);
int GetYear() const { return myYear; }
// description
void SetDescription(string description) { myDescription = description; }
string GetDescription() const { return myDescription; }
private:
int myTicketNumber;
string myClientId;
int myDay;
int myMonth;
int myYear;
string myDescription;
};
// the work ticket constructor definition
WorkTicket::WorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description)
{
SetTicketNumber(ticketNumber);
SetClientId(clientId);
SetMonth(month);
SetDay(day);
SetYear(year);
SetDescription(description);
}
// set work ticket
bool WorkTicket::SetWorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description)
{
const int MAX_DAY = 31; // setting max day to 31
const int MAX_MONTH = 12; // max month to 12
const int MIN_YEAR = 2000; // the min year 2000 as specified
const int MAX_YEAR = 2099; // max year 2099 as speciified
bool valid = true;
// setting the limits
if(ticketNumber < 0 || month < 1 || month > MAX_MONTH ||
day < 1 || day > MAX_DAY ||
year < MIN_YEAR || year > MAX_YEAR)
valid = false;
else if (clientId.length() < 1 || description.length() < 1)
valid = false;
else
{
myTicketNumber = ticketNumber;
myClientId = clientId;
myDay = day;
myMonth = month;
myYear = year;
myDescription = description;
}
return valid;
}
// this is to show the work ticket, it will show everything in the console..
void WorkTicket::ShowWorkTicket() const
{
cout << "\nWork Ticket Number: " << myTicketNumber
<< "\nClient ID: " << myClientId
<< "\nDate: " << setw(2) << setfill('0') << myMonth
<< "/" << setw(2) << setfill('0') << myDay
<< "/" << myYear
<< "\nIssue: " << myDescription << endl;
}
void WorkTicket::SetTicketNumber(int ticketNumber)
{
if(ticketNumber > 0)
{
myTicketNumber = ticketNumber;
}
else
{
throw invalid_argument("Try Again.");
}
}
// WorkTicket::SetDay definition
void WorkTicket::SetDay(int day)
{
const int MIN_VALID = 1;
const int MAX_VALID = 31;
if(day >= MIN_VALID && day <= MAX_VALID)
{
myDay = day;
}
else
{
throw invalid_argument("Try Again.");
}
}
// WorkTicket::SetMonth definition
void WorkTicket::SetMonth(int month)
{
const int MIN_VALID = 1;
const int MAX_VALID = 12;
if(month >= MIN_VALID && month <= MAX_VALID)
{
myMonth = month;
}
else
{
throw invalid_argument("Try Again.");
}
}
// WorkTicket::SetYear definition
void WorkTicket::SetYear(int year)
{
const int MIN_VALID = 2000;
const int MAX_VALID = 2099;
if(year >= MIN_VALID && year <= MAX_VALID)
{
myYear = year;
}
else
{
throw invalid_argument("Try Again.");
}
}
int main()
{
const int NUMBER_OF_TICKETS = 3;
WorkTicket tickets[NUMBER_OF_TICKETS];
int ticketNumber;
string clientId;
int day;
int month;
int year;
string description;
for (int i = 0; i <NUMBER_OF_TICKETS; i++)
{
cout << "\WorkTicket [" << i << "]: " << endl;
cout << "Enter the ticket number: " << endl;
cout << "Enter the client ID: " << endl;
getline(cin, clientId);
day = SetDay("Enter a day number: ");
}
}
Gather the input and then construct a WorkTicket. Push the tickets into a vector. In the code yet to be written, the newly create WorkTickets can be tested for correctness.
Make sure to include vector at the top of the file.
int main()
{
const int NUMBER_OF_TICKETS = 3;
int ticketNumber;
string clientId;
int day;
int month;
int year;
string description;
std::vector<WorkTicket> tickets;
for (int i = 0; i <NUMBER_OF_TICKETS; i++)
{
cout << "WorkTicket [" << i << "]: " << endl;
cout << "Enter the ticket number: " << endl;
cin>> ticketNumber;
cout << "Enter the client ID: " << endl;
cin >> clientId;
cout << "Enter a day number: " << endl;
cin >> day;
cout << "Enter a month number: " << endl;
cin>> month;
cout << "Enter a year number: " << endl;
cin>> year;
cout << "Enter a description : " << endl;
cin >> description;
try {
tickets.push_back({ticketNumber, clientId, month, day, year, description});
}
catch(std::exception e)
{
std::cout << e.what() << std::endl;
}
}
}
Assuming the rest of your code works correctly and you only have problems in the main:
There are a few issues as commented by others in your code in main:
1) You declared WorkTicket tickets[NUMBER_OF_TICKETS]; but have not used it anywhere.
2) The variable tickets is an array and therefore in the for loop tickets[i] is of type WorkTicket.
3) SetDay is a member function of WorkTicket and takes int as argument.
In light of these, following changes made:
for (int i = 0; i <NUMBER_OF_TICKETS; i++)
{
cout << "\WorkTicket [" << i << "]: " << endl;
cout << "Enter the ticket number: " << endl;
cout << "Enter the client ID: " << endl;
getline(cin, clientId);
cout<<"Enter a day number:";
int day;
cin>>day;
tickets[i].SetDay(day); //day is int and tickets[i] is of WorkTicket
}
Hope this helps to understand the main part better.

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

Segmentation Fault while passing a pointer array of classes [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 6 years ago.
Improve this question
I am having a fairly frustrating issue where I attempt to pass the contents of a pointer array that is filled with objects to another class so that I may print the contents of the Array but no matter what I have tried to do in changing the way I pass the array I consistently get a Segmentation Fault. I have looked all around for people with similar problems and I did not manage find anyone with the same issue but still I apologize if this is a duplicate question!
anyways, my code for these two classes is
#include <iostream>
#include <vector>
#include <string>
using namespace std;
//Time Class
class Time{
public:
Time();
void setHour(int sHour){hour = sHour;}
void setMinute(int sMinute){minute = sMinute;}
void setAmPm(int sAmPm){ampm = sAmPm;}
int getHour(){return hour;}
int getMinute(){return minute;}
int getAmPm(){return ampm;}
private:
int hour;
int minute;
int ampm;
};
//Time Constructor implementation
Time::Time(){
hour = 0;
minute = 0;
ampm = 0;
}
//Event Class
class Event{
public:
Event(string x, Time y);
void setDesc(string sDesc){description = sDesc;}
string getDesc(){return description;}
void setTime(Time t, int h, int m, int ampm){t.setHour(h); t.setMinute(m); t.setAmPm(ampm);}
Time getTime(){return eventTime;}
printEvent(Event e){
Time t = e.getTime();
cout << description << endl;
string ampm ="";
if(t.getAmPm() == 0)
ampm = "AM";
else
ampm = "PM";
cout << t.getHour() << ":" << t.getMinute() << " in the " << ampm;
}
private:
string description;
Time eventTime;
};
//Event Constructor implementation
Event::Event(string cDesc, Time t){
description = cDesc;
eventTime = t;
}
//Month Class
class Month{
public:
Month(string x, int y);
void addEvent(string desc, int h, int m, int ampm, int day){
Time t;
t.setHour(h);
t.setMinute(m);
t.setAmPm(ampm);
Event e(desc, t);
this -> event[day] = &e;
}
void deleteEvent(int day){delete event[day];}
Event getEvent(int day){
return *event[day];
}
void displayEvent(int day){
Event e = getEvent(day);
e.printEvent(e);
}
void displayAll(int days){
// Time t;
// Event e("StupidSolution", t);
// for(int i = 0; i < days; i++)
// e.printEvent(*event[i]);
}
private:
int days;
string month;
Event* event[31];
};
//Month Constructor implementation
Month::Month(string cMonth, int cDays){
days = cDays;
month = cMonth;
}
//both num days and find month are used to determine the Month the user wants to generate a calendar for and the amount of days in that month
string findMonth(int numMonth){
if(numMonth == 1)
return "January";
if(numMonth == 2)
return "February";
if(numMonth == 3)
return "March";
if(numMonth == 4)
return "April";
if(numMonth == 5)
return "May";
if(numMonth == 6)
return "June";
if(numMonth == 7)
return "July";
if(numMonth == 8)
return "August";
if(numMonth == 9)
return "September";
if(numMonth == 10)
return "October";
if(numMonth == 11)
return "November";
if(numMonth == 12)
return "December";
}
int numDays(int numMonth){
if(numMonth == 1)
return 31;
if(numMonth == 2)
return 28;
if(numMonth == 3)
return 31;
if(numMonth == 4)
return 30;
if(numMonth == 5)
return 31;
if(numMonth == 6)
return 30;
if(numMonth == 7)
return 31;
if(numMonth == 8)
return 31;
if(numMonth == 9)
return 30;
if(numMonth == 10)
return 31;
if(numMonth == 11)
return 30;
if(numMonth == 12)
return 31;
}
//gets all necessary info from user for creating a new event
void newEvent(int day, Month month){
string desc = "";
int h = 0;
int m = 0;
int ampm = 0;
cin.get();
cout << "Please enter a Brief Description of the Event!: " << endl;
getline(cin, desc);
cout << "Please enter the Hour of event(1-12): " << endl;
cin >> h;
cout << "Please enter the Minute of event (0-59): " << endl;
cin >> m;
cout << "Please enter 0 if it is in the AM and 1 if it is in the PM: " << endl;
cin >> ampm;
month.addEvent(desc, h, m, ampm, day);
}
int main(void){
string month = "";
int numMonth = 0;
int menuChoice = 0;
int menuLoop = 0;
int days = 0;
int eDay = 0;
cout << "please enter the month you would like to track(1-12): ";
cin >> numMonth;
days = numDays(numMonth);
month = findMonth(numMonth);
Month m(month,days);
while(menuLoop == 0){
cout << "Event Calendar for the month of " << month << endl;
cout << "1. Create a new Event" << endl;
cout << "2. Delete an existing Event" << endl;
cout << "3. Display Event for a particular day" << endl;
cout << "4. Display All Events" << endl;
cout << "5. Exit Program" << endl;
cout << "Enter Choice: " << endl;
cin >> menuChoice;
switch(menuChoice){
case 1:
cout << "What day would you like this event to be on?" << endl;
cin >> eDay;
if(eDay > 0 && eDay <= days)
newEvent(eDay, m);
else cout << "Invalid Day";
break;
case 2:
cout << "What day would you like to clear of events?" << endl;
cin >> eDay;
if(eDay > 0 && eDay <= days)
m.deleteEvent(eDay);
break;
case 3:
cout << "What day would you like to View?" << endl;
cin >> eDay;
if(eDay > 0 && eDay <= days)
m.displayEvent(eDay);
break;
case 4:
cout << "Displaying all Events.";
m.displayAll(days);
break;
case 5:
cout << "Goodbye!" << endl;
menuLoop++;
break;
default:
cout << "incorrect input";
break;
}
}
}
The important bits are the Event* event[31]; array, the displayEvent and the PrintEvent functions. I have tried all forms of passing by reference and de-referencing the array as I pass it but nothing seems to fix the issue...
Thank you so much!
Edit: added the remainder of the program, the segmentation fault occurred after creating a new event (option 1 on the menu) then either trying to delete it (option 2) or display it (option 3)
This function:
void addEvent(string desc, int h, int m, int ampm, int day){
Time t;
t.setHour(h);
t.setMinute(m);
t.setAmPm(ampm);
Event e(desc, t);
this -> event[day] = &e;
}
Creates a new Event e on the stack. Then it saves a pointer to that local variable. As soon as your function returns, that pointer is no longer valid and using it will result in undefined behavior (such as a seg fault, but it could do many other things).
To fix it, work out whether those arrays should be arrays of pointers, or just arrays of objects. If you definitely want to use pointers, then you will need to work out how you control their life time. Alternatively, you could use a smart pointer that will look after the object's lifetime for you.
Note: this is just the first thing that jumped out at me, there may be other problems.

Debug error, abort() has been called in c++

I'm trying to perform error checking on my initializer value for date, so that a day or month outside the acceptable range will stop the program from debbuging, but I'm getting a debug error even for the acceptable range. I don't know where the error is from, so i posted the code.
// ConsoleApplication56.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#include<stdexcept>
#include<array>
using namespace std;
class Date
{
public:
explicit Date(int mo, int da, int ye)
{
setDate( mo, da, ye);
}
void setDate(int &m, int &d, int &y)
{
setMonth(m);
setDay(d);
setYear(y);
}
void setMonth(int &m)
{
if (month>0 && month <13)
{
month = m;
}else
throw invalid_argument("month must be 1-12");
}
unsigned int getMonth()const
{
return month;
}
void setDay(int &d)
{
if(day>0 && day<32)
{
day = d;
}else
throw invalid_argument("day must be 0-31");
}
unsigned int getDay()const
{
return day;
}
void setYear(int &y)
{
year = y;
}
unsigned int getYear()const
{
return year;
}
void print()
{
cout<< month <<'/' << day << '/' << year;
}
void nextDay()
{
int numberOfDaysToAdd = 1;
array <int,12> daysInAMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
cout << "the date before is: " << month << "/" << day << "/" << year << endl;
day += numberOfDaysToAdd;
while (day > daysInAMonth [month - 1 ] )
{
day-= daysInAMonth [month - 1 ];
month++;
if (month > 12){
month = 1;
year++;
}
}
cout << "the day after is: " << month << "/" << day << "/" << year << endl;
}
private:
unsigned int month;
unsigned int day;
unsigned int year;
};
int main()
{
char response = 'y';
Date date(12, 3, 2013 );
cout<<"The date is :";
date.print();
cout<<endl;
cout<<endl;
cout<<"do you wish to check the next date(y/n)? :";
cin >> response;
cout<<endl;
while(response == 'y')
{
date.nextDay();
cout<<endl;
cout<<"do you wish to check the next date(y/n)? : ";
cin >> response;
cout<<endl;
}
return 0;
}
You should check the m and d values not the month and day member variables.
void setMonth(int &m)
{
if (month>0 && month <13)
should be
void setMonth(int &m)
{
if (m>0 && m <13)