C++ Function Issue - c++

A while ago I was given the task of converting a Java program to C++.
I've done this, and I've started encountering some odd errors that don't seem to make any sense to me.
The program consists of three files. A main.ccp, a date.ccp and a date.h.
main.ccp
#include <cstdlib>
#include <iostream>
#include "Date.h"
using namespace ::std;
string weekday(Date date);
int main() {
int day, month, year;
cout << "What date (d m y)? ";
cin >> day >> month >> year;
Date event = Date(day, month, year);
cout << ("That was a " + weekday(event));
return 0;
}
string weekday(Date date) {
const string days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
Date trial = Date(1, 1, 1);
int weekday = 6;
if (Date::precedes(trial)) {
return "Mysteryday";
} else {
while (trial.precedes(date)) {
trial.advance();
weekday = (weekday + 1) % 7;
}
return days[weekday];
}
}
Date.ccp
#include "Date.h"
Date::Date(int day, int month, int year) {
day_ = day;
month_ = month;
year_ = year;
}
int Date::getDay () {
return day_;
}
void Date::setDay (int day) {
day_ = day;
}
int Date::getMonth () {
return month_;
}
void Date::setMonth (int month) {
month_ = month;
}
int Date::getYear () {
return year_;
}
void Date::setYear (int year) {
year_ = year;
}
bool Date::isLeapYear () {
bool lear = false;
if (this->year_ <= 1752) {
if (this->year_ % 4 == 0) {
lear = true;
}
}
else {
lear = false;
}
if (this->year_ > 1752) {
if (this->year_ % 4 == 0 && this->year_ % 100 != 0) {
lear = true;
}
else if (this->year_ % 4 == 0 && this->year_ % 100 == 0 && this->year_ % 400 == 0) {
lear = true;
}
else {
lear = false;
}
}
return lear;
}
int Date::daysInMonth () {
// "30 days hath September ... "
switch (this->month_) {
case 9 :
case 4 :
case 6 :
case 11 :
return 30;
default :
return 31;
case 2 :
return this->isLeapYear() ? 29 : 28;
}
}
void Date::advance () {
this->day_;
if (this->day_ == 3 && this->month_ == 9 && this->year_ == 1752) {
day_ = 14;
month_ = 9;
year_ = 1752;
}
if (this->day_ > this->daysInMonth()) {
this->day_ = 1;
this->month_++;
}
if (this->month_ > 12) {
this->month_ = 1;
this->year_++;
}
}
bool Date::precedes (Date date) {
return this->year_ < date->year_
|| this->year_ == date->year_ && this->month_ < date->month_
|| this->year_ == date->year_ && this->month_ == date->month_ && this->day_ < date->day_;
}
Date.h
#ifndef DATE_H
#define DATE_H
class Date {
public:
Date (int day, int month, int year);
int getDay();
void setDay();
int getMonth();
void setMonth();
int getYear();
void setYear();
bool isLeapYear();
int daysInMonth();
void advance();
bool precedes(Date date);
private:
int day_;
int month_;
int year_;
};
#endif /* DATE_H */
I seem to be getting lots of the same errors when I compile.
Date.cpp:97:95: error: base operand of ‘->’ has non-pointer type ‘Date’
I'm not sure if I've done the declaration right or not.

You forgot to put semicolons after your class's closing }.

The class definition for Date is not terminated with a semicolon. Because you #included this file in main.cpp, the first statement after the header is the one that won't parse due to this syntax error; thus you get the error in the wrong place.

Related

Comparing data in array of objects using a member boolean function

First I need to compare the date of births in the array with the operator== function which is in the class Person, and also show the person with the earliest date of birth with the operator< function which is also in class Person. But I have trouble understanding what I'm doing wrong.
I was thinking of showing the earliest date of birth operator< using the same way as I did with operator== but now that it doesn't work, I have no idea.
#include <iostream>
#include <string>
using namespace std;
class Birth_date
{
private:
unsigned int day{};
unsigned int month{};
unsigned int year{};
public:
Birth_date() {}
Birth_date(int day, int month, int year)
{
this->day = day;
this->month = month;
this->year = year;
}
Birth_date(const Birth_date& birth)
{
day = birth.day;
month = birth.month;
year = birth.year;
}
void set_day(int day)
{
this->day = day;
}
void set_month(int month)
{
this->month = month;
}
void set_year(int year)
{
this->year = year;
}
int get_day()
{
return day;
}
int get_month()
{
return month;
}
int get_year()
{
return year;
}
friend bool operator == (const Birth_date& a, const Birth_date& b)
{
return (a == b);
}
bool operator < (const Birth_date& bd)
{
return day < bd.day && month < bd.month && year < bd.year;
}
bool operator > (const Birth_date& bd)
{
return day > bd.day && month > bd.month && year > bd.year;
}
ostream& Output(ostream& out)
{
out << "Date of birth: " << day << "/" << month << "/" << year << endl;
return out;
}
};
class Person
{
private:
string name;
Birth_date dob;
public:
Person() {}
Person(string name, Birth_date dob)
{
this->name = name;
this->dob = dob;
}
Person(const Person& p)
{
name = p.name;
dob = p.dob;
}
string get_name()
{
return name;
}
Birth_date get_dob()
{
return dob;
}
bool operator < (const Person& p)const
{
Birth_date bd1 = p.dob;
Birth_date bd2 = p.dob;
return (bd1 < bd2);
}
bool operator == (const Person& p)const
{
return (dob == p.dob);
}
const ostream& output(ostream& out)
{
out << "Name: " << name << "\t" ;
dob.Output(out);
return out;
}
};
int main()
{
Person students[5] = { Person("Ivan Petkov",Birth_date(10,6,1999)),
Person("Gabe Trent",Birth_date(20,12,1996)),
Person("Maggy Sommer",Birth_date(5,2,2000)),
Person("Cameron Dallas",Birth_date(1,4,2001)),
Person("Catherine Crumb",Birth_date(28,8,2000)) };
for (int i = 0; i < 5; i++)
{
students[i].output(cout);
}
cout << "\n";
for (int i = 0; i < 5; i++)
{
for (int x = i + 1; x < 5; x++)
{
if (students[i].operator==(students[x]))
{
cout << "Students " << students[i].get_name()
<< "and " << students[x].get_name()
<< "have the same date of birth." << endl;
}
else
cout << "Nobody has the same date of birth." << endl;
}
}
return 0;
}
Right now the only output is the array and then the program just exits.
When you're comparing dates there's the possibility that the year and the month are the same but the day is different.
21/4/2003 > 20/4/2003
however in your code you check that the month and year are greater and can't be equal.
return day < bd.day && month < bd.month && year < bd.year;
by your code if the dates are: 29/1/2000 and 1/3/2000 it would return false.
your functions should first check if the years are not the same, if they are then you next check the months and then the days.
Here's an example of a code I once wrote:
bool MyDate::operator >(const MyDate& d)const {
if (year < d.year)
return false;
else if (year > d.year)
return true;
else if (year == d.year) {
if (month < d.month)
return false;
else if (month > d.month)
return true;
if (month == d.month) {
if (day < d.day)
return false;
else if (day > d.day)
return true;
else
return false;
}
}
return true;
}

Error: candidate constructor not viable: requires 5 arguments, but 0 were provided

I'm having an issue with my project. It keeps saying there is an issue with a constructor, but I can't find the issue. I'm sorry for the length of the code, and I'm sure it is something silly I am missing.
Pardon my headers...
DateTime.h
using namespace std;
//Constant array containing the days in the given month
const int DAYS_OF_MONTH[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//Custom Date/Time format with a year that 1/1 is a sunday (Ex. 2017) to make things simpler
class DateTime {
int month, day, hour, minute;
public:
//Creates a basic blank DateTime
DateTime() {
month = 1;
day = 1;
hour = 0;
minute = 0;
}
//Creates a DateTime with a specific Date and Time
DateTime(int m, int d, int h, int min) {
month = m;
day = d;
hour = h;
minute = min;
}
//Adds the days to the date and updates the month if the day goes over
void addDays(int d) {
try {
for(int i = 0; i < d; i++) {
day++;
if(day > DAYS_OF_MONTH[month-1]) {
month++;
day = 1;
}
}
}
catch(string ex) {
}
}
//Adds a week onto the Date
void addWeeks(int w) {
for(int i = 0; i < w; i++) {
addDays(7);
}
}
//Accessors
int getMonth() {
return month;
}
int getDay() {
return day;
}
int getHour() {
return hour;
}
int getMinute() {
return minute;
}
//Mutators
void setMonth(int newM) {
month = newM;
}
void setDay(int newD) {
day = newD;
}
void setHour(int newH) {
hour = newH;
}
void setMinute(int newM) {
minute = newM;
}
};`
Day.h
#include<string>
#include "DateTime.h"
class Day {
DateTime startTime;
DateTime endTime;
int weekOfYear;
int dayOfWeek;
public:
//Creates a blank day
Day() {
startTime = DateTime(1, 1, 0, 0);
endTime = DateTime(1, 1, 0, 0);
weekOfYear = 0;
dayOfWeek = 0;
}
//Creates a blank day with a specific date
Day(int wOfY, int dOfW) {
startTime = DateTime(1, 1, 0, 0);
endTime = DateTime(1, 1, 0, 0);
weekOfYear = wOfY;
dayOfWeek = dOfW;
//Add weeks of the year and days of the week to the date
startTime.addDays(dOfW-1);
startTime.addWeeks(wOfY-1);
endTime.addDays(dOfW-1);
endTime.addWeeks(wOfY-1);
}
//Create a filled day with specific date and start/end times
Day(int wOfY, int dOfW, int startHr, int startMin, int endHr, int endMin) {
startTime = DateTime(1, 1, startHr, startMin);
endTime = DateTime(1, 1, endHr, endMin);
weekOfYear = wOfY;
dayOfWeek = dOfW;
}
//Accessors
DateTime getStartTime() {
return startTime;
}
DateTime getEndTime() {
return endTime;
}
int getWeekOfYear() {
return weekOfYear;
}
int getDayOfWeek() {
return dayOfWeek;
}
//Mutators
void setStartTime(DateTime newTime) {
startTime = newTime;
}
void setEndTime(DateTime newTime) {
endTime = newTime;
}
void setWeekOfYear(int newWOfY) {
weekOfYear = newWOfY;
}
void setDayOfWeek(int newDOfW) {
dayOfWeek = newDOfW;
}
//Calculates the amount of time between startTime and endTime
float getDailyHours() {
if((float)endTime.getHour() - (float)startTime.getHour() >=1) {
return ((60- (float)startTime.getMinute())/60) + ((float)endTime.getHour() - (float)startTime.getHour() - 1) + ((float)endTime.getMinute() / 60);
}
else {
return ((float)endTime.getMinute() - (float)startTime.getMinute()) / 60;
}
}
//Returns the data of the day in the format to save to the file
string toString() {
return string(",") + to_string(dayOfWeek) + string(",") + to_string(startTime.getHour()) + string(",") + to_string(startTime.getMinute()) + string(",") + to_string(endTime.getHour()) + string(",") + to_string(endTime.getMinute());
}
};
Week.h
#include "Day.h"
#include <vector>
using namespace std;
class Week {
vector<Day> dayList;
float totalWeeklyHours;
int weekOfYear;
public:
//Creates a basic week
Week(int wOfY) {
//dayList.resize(7);
weekOfYear = wOfY;
for(int i = 0; i < 7; i++) {
dayList.push_back(Day(weekOfYear, i));
}
}
//Creates a week given a dayList
Week(int wOfY, vector<Day> dL) {
//dayList.resize(7);
weekOfYear = wOfY;
for(int i = 0; i < 7; i++) {
dayList.push_back(dL.at(i));
}
}
//Accessors
int getWeekOfYear() {
return weekOfYear;
}
vector<Day> getDayList() {
return dayList;
}
//Adds a day to dayList from EmployeeManager.readFile()
void addDay(int wOfY, int dOfW, int startHr, int startMin, int endHr, int endMin) {
Day temp = Day(wOfY, dOfW, startHr, startMin, endHr, endMin);
dayList.at(dOfW) = temp;
weekOfYear = temp.getWeekOfYear();
}
//Adds a day from Employee.addWeek()
void addDay(Day newDay, int dOfW) {
dayList.at(dOfW) = newDay;
weekOfYear = newDay.getWeekOfYear();
}
//Calculates the total amount of hours scheduled in the week
float getTotalWeeklyHours() {
totalWeeklyHours = 0;
for(int i = 0; i < dayList.size(); i++) {
totalWeeklyHours += dayList.at(i).getDailyHours();
}
return totalWeeklyHours;
}
//Returns the data of the week in the format to save in the file
string toString() {
return (string)"," + to_string(weekOfYear) + dayList.at(0).toString() + dayList.at(1).toString() + dayList.at(2).toString() + dayList.at(3).toString() + dayList.at(4).toString() + dayList.at(5).toString() + dayList.at(6).toString();
}
};
Person.h
#include <string>
using namespace std;
class Person {
public:
string firstName;
string lastName;
int employeeID;
int employeePIN;
float hourlyRateOfPay;
public:
Person() {
firstName = "John";
lastName = "Doe";
employeeID = 0;
employeePIN = 0;
hourlyRateOfPay = 0;
}
//Accessors
string getFirstName() {
return firstName;
}
string getLastName() {
return lastName;
}
int getEmployeeID() {
return employeeID;
}
int getEmployeePIN() {
return employeePIN;
}
float getHourlyRateOfPay() {
return hourlyRateOfPay;
}
//Mutators
void setFirstname(string newName) {
firstName = newName;
}
void setLastName(string newName) {
lastName = newName;
}
void setEmployeeID(int newID) {
employeeID = newID;
}
void setEmployeePIN(int newPIN) {
employeePIN = newPIN;
}
void setHourlyRateOfPay(float newPay) {
hourlyRateOfPay = newPay;
}
//Abstract methods
string viewSchedule(int wOfY);
float viewPay(int wOfY);
};
Employee.h
#include "Person.h"
#include "Week.h"
using namespace std;
class Employee : public Person {
vector<Week> weekList;
public:
Employee(int empID, int empPIN, string fName, string lName, float hROP) {
employeeID = empID;
employeePIN = empPIN;
firstName = fName;
lastName = lName;
hourlyRateOfPay = hROP;
/*
setEmployeeID(empID);
setEmployeePIN(empPIN);
setFirstName(fname);
setLastName(lname);
setHourlyRateOfPay(hROP);
*/
for(int i = 0; i < 52; i++) {
weekList.push_back(Week(i));
}
}
Week getWeek(int wOfY) {
return weekList.at(wOfY);
}
//Adds a week to the weekList from EmployeeManager.readFile()
void addWeek(int wOfY, vector<Day> dL) {
for(int i = 0; i < 7; i++) {
weekList.at(wOfY).addDay(dL.at(i), i);
}
}
//Adds a week from client
void addWeek(int wOfY, Week newWeek) {
weekList.at(wOfY) = newWeek;
}
//Returns a specified wek to be viewed by the user
string viewSchedule(int wOfY) {
return weekList.at(wOfY).toString();
}
//Returns the amount of pay for a specified week to be viewed by the user
float viewPay(int wOfY) {
return hourlyRateOfPay * (weekList.at(wOfY).getTotalWeeklyHours());
}
//Returns the data of the employee in the format to save to the readFile
string toString() {
return firstName + "," + lastName + "," + to_string(employeeID) + "," + to_string(employeePIN) + "," + to_string(hourlyRateOfPay);
}
};
EmployeeManager.h
#include "Employee.h"
#include <fstream>
#include <sstream>
using namespace std;
class EmployeeManager {
vector<Employee> employeeList;
public:
EmployeeManager() {
//readFile();
}
void readFile() {
//Variables
int empID, empPIN, wOfY, dOfW, startHr, startMin, endHr, endMin;
float hROP;
string fname, lname;
ifstream input;
input.open("EmployeeList.csv");
while(!input.eof()) {
input >> fname >> lname >> empID >> empPIN >> hROP;
//Create temp Employee
Employee tempEmployee = Employee(empID, empPIN, fname, lname, hROP);
for(int i = 0; i < 52; i++) {
Week tempWeek = Week(i);
input >> wOfY;
for(int j = 0; j < 7; j++) {
input >> dOfW >> startHr >> startMin >> endHr >> endMin;
tempWeek.addDay(wOfY, dOfW, startHr, startMin, endHr, endMin);
}
tempEmployee.addWeek(wOfY, tempWeek.getDayList());
}
addEmployee(tempEmployee);
}
input.close();
}
void saveFile() {
ofstream output("EmployeeList.csv");
for(int i = 0; i < employeeList.size(); i++) {
output << employeeList.at(i).toString();
for(int j = 0; j < 52; j++) {
output << employeeList.at(i).viewSchedule(j);
}
output << "\n";
}
output.close();
}
//Adds a new employee to the employeeList from readFile
void addEmployee(Employee newEmp) {
//employeeList.resize(employeeList.size()*2);
try{
employeeList.push_back(newEmp);
}
catch(out_of_range ex) {
cout << "EmployeeList out_of_range" << endl;
int newSize = employeeList.size() * 2;
employeeList.resize(newSize);
addEmployee(newEmp);
}
}
//Adds a new employee to the employeeList from client
void addEmployee(int empID, int empPIN, string fname, string lname, float hROP) {
Employee newEmp = Employee(empID, empPIN, fname, lname, hROP);
//employeeList.resize(employeeList.size()*2);
try {
employeeList.push_back(newEmp);
}
catch(out_of_range ex) {
cout << "EmployeeList out_of_range" << endl;
int newSize = employeeList.size() * 2;
employeeList.resize(newSize);
addEmployee(newEmp);
}
}
bool validateLogin(int empID, int empPIN) {
for(int i = 0; i < employeeList.size(); i++) {
if(employeeList.at(i).getEmployeeID() == empID) {
if(employeeList.at(i).getEmployeePIN() == empPIN) {
return true;
}
}
}
return false;
}
bool isIDAvailable(int empID) {
for(int i = 0; i < employeeList.size(); i++) {
if(employeeList.at(i).getEmployeeID() == empID) {
return false;
}
}
return true;
}
};
main.cpp
#include <iostream>
#include "EmployeeManager.h"
int main() {
Day d1 = Day(9,6);
cout << d1.toString() << endl;
Week w1 = Week(1);
cout <<"\n\n" << w1.toString() << endl;
Employee e1 = Employee(12345, 9876, "Test", "Employee", 15.60);
cout << "\n\n" << e1.toString();
for(int i = 0; i < 52; i++) {
cout << e1.viewSchedule(i);
}
cout << endl;
EmployeeManager em1 = EmployeeManager();
em1.saveFile();
}
Then I had a .csv file named EmployeeList.csv
This is the Error Message I was given
 clang++-7 -pthread -std=c++17 -o main main.cpp
In file included from main.cpp:2:
In file included from ./EmployeeManager.h:1:
In file included from ./Employee.h:2:
In file included from ./Week.h:2:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/vector:62:
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_construct.h:75:38: error:
no matching constructor for initialization of 'Employee'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_uninitialized.h:527:8: note:
in instantiation of function template specialization
'std::_Construct<Employee>' requested here
std::_Construct(std::__addressof(*__cur));
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_uninitialized.h:583:2: note:
in instantiation of function template specialization
'std::__uninitialized_default_n_1<false>::__uninit_default_n<Employee *,
unsigned long>' requested here
__uninit_default_n(__first, __n);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_uninitialized.h:645:19: note:
in instantiation of function template specialization
'std::__uninitialized_default_n<Employee *, unsigned long>' requested here
{ return std::__uninitialized_default_n(__first, __n); }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/vector.tcc:596:8: note:
in instantiation of function template specialization
'std::__uninitialized_default_n_a<Employee *, unsigned long, Employee>'
requested here
std::__uninitialized_default_n_a(this->_M_impl._M_finish,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:827:4: note:
in instantiation of member function 'std::vector<Employee,
std::allocator<Employee> >::_M_default_append' requested here
_M_default_append(__new_size - size());
^
./EmployeeManager.h:64:20: note: in instantiation of member function
'std::vector<Employee, std::allocator<Employee> >::resize' requested here
employeeList.resize(newSize);
^
./Employee.h:5:7: note: candidate constructor (the implicit copy constructor)
not viable: requires 1 argument, but 0 were provided
class Employee : public Person {
^
./Employee.h:5:7: note: candidate constructor (the implicit move constructor)
not viable: requires 1 argument, but 0 were provided
./Employee.h:9:5: note: candidate constructor not viable: requires 5 arguments,
but 0 were provided
Employee(int empID, int empPIN, string fName, string lName, float hROP) {
^
1 error generated.
exit status 1
Operations like employeeList.resize(newSize) in std::vector require a default constructor for the containing element, which is missed in the class Employee. This is necessary to create the empty elements in the container.
Just add the default constructor, or store pointers instead if you can't accommodate/afford the default constructor for some reason.

C++ date Type class .. after compilation some function work well but the other not

in below there is the Header File for dateType.
h class. after debug it showing in consul windows this :
Consul Image
Header File : dateType.h
#ifndef dateType_H
#define dateType_H
class dateType
{
public:
void setDate(int, int, int);
void setMonth(int);
void setDay(int);
void setYear(int);
void print() const;
int numberOfDaysPassed();
int numberOfDaysLeft();
void incrementDate(int nDays);
int getMonth();
int getDay();
int getYear();
int getDaysInMonth();
bool isLeapYear();
dateType(int = 1, int = 1, int = 1900);
private:
int dMonth;
int dDay;
int dYear;
};
#endif
main() Function :
#include <iostream>
#include<time.h>
#include "dateType.h"
using namespace std;
int main ()
{
cout <<" Program work with data type"<<endl;
dateType myDate(1,1,1900);
cout << "\n\n The current Date is : "<<endl;
myDate.print();
cout <<endl;
cout <<"\n\n days in this year are :" <<endl;
myDate.getDaysInMonth();
cout <<endl;
cout <<"\n\n Days passed in this year are :"<<endl;
myDate.numberOfDaysPassed();
cout <<endl;
cout <<"\n\n Days remaining in this year are :"<<endl;
myDate.numberOfDaysLeft();
cout <<endl;
myDate.incrementDate(7);
cout <<"\n\n New date after adding days is "<<endl;
cout <<endl;
myDate.print();
cout <<endl;
system("pause");
return 0;
}
Implementation file .cpp :
#include <iostream>
#include "dateType.h"
using namespace std;
void dateType::setDate(int month,int day,int year)
{
setYear(year);
setMonth(month);
setDay(day);
}
void dateType::setMonth(int month)
{
if(month > 0 && month < 13)
dMonth =month;
else
dMonth = 1;
}
void dateType::setDay(int day)
{
int days[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
if (isLeapYear())
days[1]++;
if(day >= 1 && day <=days [dMonth -1])
dDay =day;
else
dDay =1;
}
void dateType::setYear(int year)
{
if (((int)log10((double)year) + 1)!=4)
dYear = 1990;
else dYear = year;
}
int dateType::getDaysInMonth()
{
int days[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
if (isLeapYear())
days[1]++;
return days[ dYear -1 ];
}
int dateType::numberOfDaysPassed()
{
int days[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
int m, daysPassed;
if (isLeapYear())
days[1]++;
m = dYear-1;
daysPassed=0;
while(m>0)
{
daysPassed+= days[m-1];
m--;
}
daysPassed+= dDay;
return daysPassed;
}
int dateType::numberOfDaysLeft()
{
int daysRemaining=365;
if (isLeapYear())
daysRemaining++;
daysRemaining-= numberOfDaysPassed();
return daysRemaining;
}
void dateType::incrementDate(int nDays)
{
while ((nDays + dDay) > dateType::getDaysInMonth())
{
nDays -= dateType::getDaysInMonth();
if (dMonth == 12)
{
dMonth = 0;
dYear++;
}
dMonth++;
}
dDay += nDays;
}
int dateType::getDay()
{
return dDay;
}
int dateType::getMonth()
{
return dMonth;
}
int dateType::getYear()
{
return dYear;
}
void dateType::print() const
{
cout <<"\n\t"<<dMonth<<"-"<<dDay<<"-"<<dYear;
}
dateType::dateType(int month, int day, int year)
{
setDate(month,day,year);
}
bool dateType::isLeapYear()
{
if (dYear % 400 == 0 || ( dYear % 100 !=0 && dYear % 4 ==0))
return true;
else
return false;
}
I am not sure about calculating I thing i did wrong with these :
days in this year are :
Days passed in this year are :
Days remaining in this year are :
The functions getDaysInMonth, numberOfDaysPassed and numberOfDaysLeft don't print anything, they only return a value.
You have to print the value, so something like std::cout << myDate.getDaysInMonth() << '\n';
You print days in this year are :, but the function you call is getDaysInMonth. I don't know which one you need, but the logic is for both wrong.
If you need the days in the year, then you only need to return 365 or 366, depending if it is a leap year or not.
If you need the days in the month, you should decrement dMonth instead of dYear, as you want the month, and not the year (because you are currently use the year as index, you're accessing memory you don't own, which will result in an access violation exception or some random value).
The function numberOfDaysPassed calculates m as follows m = dYear - 1;, but again, you should be using dMonth. You should also consider using a for loop instead of a while:
for (int i = dMonth - 1; i > 0; --i)
daysPassed += days[i - 1];

Overloading the '-' operator

Currently I'm writing a program that has a section to determine the difference in days between two dates, but by overloading the minus operator.
I'm currently staring at my screen drawing a complete blank. I have some fleeting thoughts in my head but they are exactly that, fleeting.
What's to happen in the main.cpp is that there are going to be two variables, for instance beethovenDeathDate and beethovenBirthDate that will be subtracted to determine how long he lived for. Which is something around 22000 days if I recall correctly.
So without further ado, here is my code:
Date.cpp
const std::string Date::MONTH_STRINGS[] =
{
"", //one based indexing
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
const int Date::DAYS_PER_MONTH[] =
{
0, //one based indexing
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
Date::Date(int day, int month, int year) : _year(year), _month(month), _day(day)
{
isValid();
}
Date::Date()
{
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
_year = now -> tm_year + 1900;
_month = now -> tm_mon + 1;
_day = now -> tm_mday;
}
int Date::maxDay(int month, int year)
{
int ret = DAYS_PER_MONTH[month];
if(isLeapYear(year) == true && month == 2)
{
++ret;
}
return ret;
}
void Date::addDay(bool forward)
{
if(forward)
{
if(_day < maxDay(_month, _year))
{
++_day;
}
else
{
_day = MIN_DAY;
++_month;
if(_month > MAX_MONTH)
{
_month = MIN_MONTH;
++_year;
}
}
}
else
{
if(_day <= MIN_DAY)
{
--_month;
if(_month < MIN_MONTH)
{
_month = MAX_MONTH;
--_year;
}
_day = maxDay(_month, _year);
}
else
{
--_day;
}
}
}
std::string Date::toString() const
{
if(isValid() == false)
{
return std::string();
}
std::stringstream ss;
ss << MONTH_STRINGS[_month] << " " << _day << ", " << _year;
return ss.str();
}
bool Date::isValid() const
{
if(_month < MIN_MONTH || _month > MAX_MONTH)
{
std::cerr << "Invalid date " << std::endl;
return false;
}
int daysThisMonth = maxDay(_month, _year);
if(_day < MIN_DAY || _day > daysThisMonth)
{
std::cerr << "Invalid date " << std::endl;
return false;
}
return true;
}
bool Date::isLeapYear(int year)
{
if(!(year % 4))
{
if(!(year % 100))
{
if(!(year % 400))
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
else
{
return false;
}
}
bool Date::isLeapYear() const
{
return isLeapYear(_year);
}
bool Date::isLeapDay() const
{
return isLeapDay(_day, _month, _year);
}
bool Date::isLeapDay(int day, int month, int year)
{
if(day == 29 && month == 2 && isLeapYear(year) == true)
{
return true;
}
else
{
return false;
}
}
void Date::addYears(int years)
{
if(years == 0)
{
return;
}
if(isLeapDay() && !isLeapDay(_day, _month, _year + years))
{
_day = Date::DAYS_PER_MONTH[_month];
}
_year += years;
}
void Date::addMonths(int months)
{
if(months == 0)
{
return;
}
int deltayears = months / MAX_MONTH;
int deltamonths = months % MAX_MONTH;
int newMonth = 0;
if(months > 0)
{
newMonth = (_month + deltamonths) % MAX_MONTH;
if((_month + deltamonths) > MAX_MONTH)
{
++deltayears;
}
}
else
{
if((_month + deltamonths) < MIN_MONTH)
{
--deltayears;
newMonth = _month + deltamonths + MAX_MONTH;
}
else
{
newMonth = _month + deltamonths;
}
}
if(_day > maxDay(newMonth, _year + deltayears))
{
_day = maxDay(newMonth, _year + deltayears);
}
_year += deltayears;
_month = newMonth;
}
void Date::addDays(int days)
{
if(days == 0)
{
return;
}
if(days < 0)
{
for(int i = 0; i > days; --i)
{
addDay(false);
}
return;
}
for(int i = 0; i < days; ++i)
{
addDay(true);
}
}
std::ostream& operator<<(std::ostream& os, const Date& date)
{
os << date.toString();
return os;
}
Date Date::operator+(int days) const
{
Date ret = *this;
ret.addDays(days);
return ret;
}
Date& Date::operator+=(int days)
{
addDays(days);
return *this;
}
//This is where I get stumped (the parameters was just one of my failed experiments
Date& Date::operator-(int day, int month, int year)
{
}
The function can be written either as a member, or as a free function. The member function signature would look like this:
TimeDuration Date::operator-(Date const & rhs) const
The free function would look like this:
TimeDuration operator-(Date const & lhs, Date const & rhs)
TimeDuration here is a completely seperate type representing a length of time. If you want, you could just make it an int signifying the number of days, but it would be better, in my opinion, to have a more expressive type for this purpose. Whatever you decide regarding the return type, it doesn't make any sense for the type to be Date (and certainly not Date&).
A possible (albeit not incredibly efficient) implementation, given that you've already written a function to add a day to a date, would be something like this:
if lhs_date comes before rhs_date
add days to (a copy of) lhs_date until lhs_date == rhs_date
return the negative of number of days added
if rhs_date comes before lhs_date
add days to (a copy of) rhs_date until rhs_date == lhs_date
return the number of days added
else
return 0
Another function you might want (or maybe this is what you actually wanted originally, but your wording doesn't indicate it) is a function which can subtract a length of time from a Date. In that case, the return value would be another Date object (but not Date&), and the possible signatures would look something like this:
Date Date::operator-(TimeDuration rhs) const // member version
Date operator-(Date const & lhs, TimeDuration const & rhs) // non-member version
You should do this:
//This is where I get stumped (the parameters was just one of my failed experiments
TimeDuration& Date::operator-(Date const & d1)
{
// ... processing ...
// this - d1;
}
and call it as:
Date d1 = new Date(20, 01, 2013);
TimeDuration duration = d1 - (new const Date(20, 01, 1922));
// Calculate no. of days or years using duration
The logic is as follows:
Pass two Date objects (first could be implicit) to the overloading function and return TimeDuration
To invoke this operator, you may create a Date object with the data that you have, instead of passing each value separately.
Please check for exact syntax.

C++ Runtime Function Hang

After much error shooting, I've got a compiling program that runs, but encounters an issue.
It will hang at a certain point, when it seems to call a function.
Main.ccp
#include <cstdlib>
#include <iostream>
#include "Date.h"
using namespace ::std;
string weekday(Date date);
int main() {
int day, month, year;
cout << "What date (d m y)? ";
cin >> day >> month >> year;
Date event (day, month, year);
cout << ("That was a " + weekday(event));
return 0;
}
string weekday(Date date) {
const string days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
Date trial (1, 1, 1);
int weekday = 6;
if (date.precedes(trial)) {
return "Mysteryday";
} else {
while (trial.precedes(date)) {
trial.advance();
weekday = (weekday + 1) % 7;
}
return days[weekday];
}
}
Date.ccp
#include "Date.h"
Date::Date(int day, int month, int year) {
day_ = day;
month_ = month;
year_ = year;
}
int Date::getDay () {
return day_;
}
void Date::setDay (int day) {
day_ = day;
}
int Date::getMonth () {
return month_;
}
void Date::setMonth (int month) {
month_ = month;
}
int Date::getYear () {
return year_;
}
void Date::setYear (int year) {
year_ = year;
}
bool Date::isLeapYear () {
bool lear = false;
if (this->year_ <= 1752) {
if (this->year_ % 4 == 0) {
lear = true;
}
}
else {
lear = false;
}
if (this->year_ > 1752) {
if (this->year_ % 4 == 0 && this->year_ % 100 != 0) {
lear = true;
}
else if (this->year_ % 4 == 0 && this->year_ % 100 == 0 && this->year_ % 400 == 0) {
lear = true;
}
else {
lear = false;
}
}
return lear;
}
int Date::daysInMonth () {
switch (this->month_) {
case 9 :
case 4 :
case 6 :
case 11 :
return 30;
default :
return 31;
case 2 :
return this->isLeapYear() ? 29 : 28;
}
}
void Date::advance () {
this->day_;
if (this->day_ == 3 && this->month_ == 9 && this->year_ == 1752) {
day_ = 14;
month_ = 9;
year_ = 1752;
}
if (this->day_ > this->daysInMonth()) {
this->day_ = 1;
this->month_++;
}
if (this->month_ > 12) {
this->month_ = 1;
this->year_++;
}
}
bool Date::precedes (Date date) {
return this->year_ < date.year_
|| this->year_ == date.year_ && this->month_ < date.month_
|| this->year_ == date.year_ && this->month_ == date.month_ && this->day_ < date.day_;
}
Date.h
#ifndef DATE_H
#define DATE_H
class Date {
public:
Date (int day, int month, int year);
int getDay();
void setDay(int day);
int getMonth();
void setMonth(int month);
int getYear();
void setYear(int year);
bool isLeapYear();
int daysInMonth();
void advance();
bool precedes(Date date);
private:
int day_;
int month_;
int year_;
};
#endif /* DATE_H */
Under the main.ccp, the program seems to hang at this point:
} else {
while (trial.precedes(date)) {
trial.advance();
weekday = (weekday + 1) % 7;
}
If I enter values before 'trial', (Trial is 1 1 1). If I enter 0 0 0, the correct output is displayed of 'Mystery day'.
However any values after the trial value, the program will hang.
It seems to me there is an error somewhere in the Date.ccp on one of the functions such as isLeapYear, advance, or daysInMonth.
Any ideas?
Seems like the advance function
void Date::advance () {
this->day_;
// lots of checks
}
doesn't advance anything.
That will cause the while-condition to never become true.