Calendar not displaying correctly

I am trying to get my calendar to display correctly for a project in my class. The calendar requires the user to input a number (1-12) for a month and a year no earlier than 1753. I think the problem(s) might reside in the computeOffset() and/or the displayCalendar() function(s). Here is the code:

#include <iostream>
#include <iomanip>
using namespace std;
int getMonth();
int getYear();
bool isLeapYear(int year);
int dayMonth(int month, int year);
int dayYear(int year);
int computeOffset(int month, int year);
void displayTop(int month, int year);
void displayCalendar(int offset, int daysMonth);
void display(int month, int year, int offset, int daysMonth);
/**********************************************************************
* This function will ask the user for a month and year, then display
* a calendar with the month and year above.
***********************************************************************/
int main()
{
int month = getMonth();
int year = getYear();
isLeapYear(year);
int daysMonth = dayMonth(month, year);
int daysYear = dayYear(year);
int offset = computeOffset(month, year);
display(month, year, offset, daysMonth);
return 0;
}

int getMonth()
{
int month;
cout << "Enter a month number: ";
cin >> month;
while (month < 1 || month > 12)
{
cout << "Month must be between 1 and 12.\n";
cout << "Enter a month number: ";
cin >> month;
}
return month;
}

int getYear()
{
int year;
cout << "Enter year: ";
cin >> year;
while (year < 1753)
{
cout << "Year must be 1753 or later.\n";
cout << "Enter year: ";
cin >> year;
}
return year;
}

bool isLeapYear(int year)
{
if (year % 4 == 0 && year % 100 != 0)
return true;
else if (year % 400 == 0)
return true;
else
return false;
}

int dayMonth(int month, int year)
{
int daysMonth;
if (month == 1 || month == 3 || month == 5 ||
month == 7 || month == 8 || month == 10 ||
month == 12)
daysMonth = 31;
else if (month == 4 || month == 6 ||
month == 9 || month == 11)
daysMonth = 30;
else if (month == 2)
{
bool isLeap = isLeapYear(year);
if (isLeap == true)
daysMonth = 29;
else
daysMonth = 28;
}
return daysMonth;
}

int dayYear(int year)
{
bool isLeap = isLeapYear(year);
int daysYear;
if (isLeap == true)
daysYear = 366;
else
daysYear = 365;
return daysYear;
}

int computeOffset(int month, int year)
{
int numDays = 0;
int numYears = year - 1753;
for (int yearCount = 1753; yearCount < year; yearCount++)
numDays += dayMonth(month, year);
for (int monthCount = 1; monthCount < month; monthCount++)
numDays += dayMonth(month, year);
int offset = numDays % 7;
return offset;
}

void displayTop(int month, int year)
{
cout << "\n";
if (month == 1)
cout << "January";
else if (month == 2)
cout << "February";
else if (month == 3)
cout << "March";
else if (month == 4)
cout << "April";
else if (month == 5)
cout << "May";
else if (month == 6)
cout << "June";
else if (month == 7)
cout << "July";
else if (month == 8)
cout << "August";
else if (month == 9)
cout << "September";
else if (month == 10)
cout << "October";
else if (month == 11)
cout << "November";
else if (month == 12)
cout << "December";
cout << ", " << year << "\n";
cout << " Su Mo Tu We Th Fr Sa\n";
}

void displayCalendar(int offset, int daysMonth)
{
int weekday;
int day;
if (offset == 0)
{
day = 2;
cout << setw(6);
}
else if (offset == 1)
{
day = 3;
cout << setw(10);
}
else if (offset == 2)
{
day = 4;
cout << setw(14);
}
else if (offset == 3)
{
day = 5;
cout << setw(18);
}
else if (offset == 4)
{
day = 6;
cout << setw(22);
}
else if (offset == 5)
{
day = 7;
cout << setw(26);
}
else if (offset == 6)
{
day = 1;
cout << setw(2);
}
for (weekday = 1; weekday <= daysMonth; weekday++)
{
cout << " " << setw(2) << weekday;
++day;
if (day == 8)
{
cout << "\n";
day = 1;
}
}
if (day >= 2 && day <= 7)
cout << "\n";
}

void display(int month, int year, int offset, int daysMonth)
{
displayTop(month, year);
int numDays = dayMonth(month, year);
displayCalendar(offset, daysMonth);
}

Most of the tests do not work. For example, the November 2002 calendar should start on Friday, but instead displays the following:

Enter a month number: 13
Month must be between 1 and 12.
Enter a month number: -1
Month must be between 1 and 12.
Enter a month number: 11
Enter year: 90
Year must be 1753 or later.
Enter year: -1
Year must be 1753 or later.
Enter year: 2002

November, 2002
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
In main():
- you invoke isLeapYear() and then neglect its return value;
- you invoke dayYear() and save its return value into daysYear, and then you neglect it.

In computeOffset():
- you declare numYears and then you neglect it.

In display():
- you declare numDays and then you neglect it.

…[omissis]…

The compiler should have raised warnings for all these problem: I think you’d better not ignore what the compiler tells you!

Keep your code readable.
Sometimes switch is more legible than a sequence of if/else.
Don’t add an else if you don’t have to.

Please always surround your code by the code tags:
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/


Just tidying your code up, the output improves (compared to your example):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <iostream>
#include <iomanip>


int getMonth();
int getYear();
bool isLeapYear(int year);
int dayMonth(int month, int year);
int dayYear(int year);
int computeOffset(int month, int year);
void displayTop(int month, int year);
void displayCalendar(int offset, int daysMonth);
void display(int month, int year, int offset, int daysMonth);


int main()
{
    int month = getMonth();
    int year = getYear();

    int daysMonth = dayMonth(month, year);

    int offset = computeOffset(month, year);

    display(month, year, offset, daysMonth);
    return 0;
}


int getMonth()
{
    std::cout << "Enter a month number: ";
    int month;
    std::cin >> month;
    while (month < 1 || 12 < month)
    {
        std::cout << "Month must be between 1 and 12.\nEnter a month number: ";
        std::cin >> month;
    }
    return month;
}


int getYear()
{
    std::cout << "Enter year: ";
    int year;
    std::cin >> year;
    while (year < 1753)
    {
        std::cout << "Year must be 1753 or later.\nEnter year: ";
        std::cin >> year;
    }
    return year;
}


bool isLeapYear(int year)
{
    if (year % 4 == 0 && year % 100 != 0) { return true; }
    if (year % 400 == 0)                  { return true; }
    return false;
}


// Returns -1 in case of error
int dayMonth(int month, int year)
{
    switch(month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        return 31;

    case 2:
        return isLeapYear(year) ? 29 : 28 ;

    case 4: case 6: case 9: case 11:
        return 30;

    default:
        return -1;
    }
}


int dayYear(int year)
{
    return isLeapYear(year) ? 366 : 365 ;
}


int computeOffset(int month, int year)
{
    int numDays = 0;
    // int numYears = year - 1753;

    for (int yearCount = 1753; yearCount < year; ++yearCount) {
        numDays += dayMonth(month, year);        
    }

    for (int monthCount = 1; monthCount < month; monthCount++) {
        numDays += dayMonth(month, year);
    }

    return numDays % 7;
}


void displayTop(int month, int year)
{
    std::cout << "\n";
    switch(month) {
    case  1: std::cout << "January";   break;
    case  2: std::cout << "February";  break;
    case  3: std::cout << "March";     break;
    case  4: std::cout << "April";     break;
    case  5: std::cout << "May";       break;
    case  6: std::cout << "June";      break;
    case  7: std::cout << "July";      break;
    case  8: std::cout << "August";    break;
    case  9: std::cout << "September"; break;
    case 10: std::cout << "October";   break;
    case 11: std::cout << "November";  break;
    case 12: std::cout << "December";  break;
    }
    std::cout << ", " << year << "\n";
    std::cout << " Su Mo Tu We Th Fr Sa\n";
}


void displayCalendar(int offset, int daysMonth)
{
    int weekday;
    int day;
    switch(offset) {
    case 0:
        day = 2;
        std::cout << std::setw(6);
        break;
    case 1:
        day = 3;
        std::cout << std::setw(10);
        break;
    case 2:
        day = 4;
        std::cout << std::setw(14);
        break;
    case 3:
        day = 5;
        std::cout << std::setw(18);
        break;
    case 4:
        day = 6;
        std::cout << std::setw(22);
        break;
    case 5:
        day = 7;
        std::cout << std::setw(26);
        break;
    case 6:
        day = 1;
        std::cout << std::setw(2);
        break;
    }

    for (weekday = 1; weekday <= daysMonth; ++weekday)
    {
        std::cout << ' ' << std::setw(2) << weekday;
        ++day;
        if (day == 8)
        {
            std::cout << "\n";
            day = 1;
        }
    }
    if (day >= 2 && day <= 7)
    std::cout << "\n";
}

void display(int month, int year, int offset, int daysMonth)
{
    displayTop(month, year);
    // int numDays = dayMonth(month, year);
    displayCalendar(offset, daysMonth);
}


Output:
Enter a month number: 11
Enter year: 2002

November, 2002
 Su Mo Tu We Th Fr Sa
       1  2  3  4  5  6
  7  8  9 10 11 12 13
 14 15 16 17 18 19 20
 21 22 23 24 25 26 27
 28 29 30


There are probably other issues I’m too lazy to look at :-/ but someone else’s likely to spot them.

Unfortunately, this fails all of the tests because the offset is wrong. The 1st of November 2002 starts on Friday.
Topic archived. No new replies allowed.