Calender Program

Pages: 12
closed account (oG8qGNh0)
Write a program that collects from the user only two pieces of information – (1) the year and (2) the day of the week on which January 1st of that year falls. The first day of the month will be inputted as an integer ranging from 0 (Sunday) through 6 (Saturday). You may assume there will be no malicious input.

Your program will then generate a calendar for the entire year. Your solution must incorporate a for loop to control the days. Don’t forget to comment – at top and at each major step to explain).

I have everything but the 2 steps (1) the year and (2) the day of the week on which January 1st of that year falls.

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
#include<iostream>
#include<cmath>
#include<bits/stdc++.h> 
using namespace std; 

int dayNumber(int day, int month, int year) 
{ 
  
static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; 
year -= month < 3; 
return ( year + year/4 - year/100 + year/400 + t[month-1] + day) % 7; 
} 

string getMonthName(int monthNumber) 
{ 
string months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; 
return (months[monthNumber]); 
} 
  
int numberOfDays (int monthNumber, int year) 
{ 
    // January 
    if (monthNumber == 0) 
        return (31); 
  
    // February 
    if (monthNumber == 1) 
    { 
        // If the year is leap then February has 
        // 29 days 
        if (year % 400 == 0 || 
                (year % 4 == 0 && year % 100 != 0)) 
            return (29); 
        else
            return (28); 
    } 
  
    // March 
    if (monthNumber == 2) 
        return (31); 
  
    // April 
    if (monthNumber == 3) 
        return (30); 
  
    // May 
    if (monthNumber == 4) 
        return (31); 
  
    // June 
    if (monthNumber == 5) 
        return (30); 
  
    // July 
    if (monthNumber == 6) 
        return (31); 
  
    // August 
    if (monthNumber == 7) 
        return (31); 
  
    // September 
    if (monthNumber == 8) 
        return (30); 
  
    // October 
    if (monthNumber == 9) 
        return (31); 
  
    // November 
    if (monthNumber == 10) 
        return (30); 
  
    // December 
    if (monthNumber == 11) 
        return (31); 
} 
  
// Function to print the calendar of the given year 
void printCalendar(int year) 
{ 
    printf ("         Calendar - %d\n\n", year); 
    int days; 
  
    // Index of the day from 0 to 6 
    int current = dayNumber (1, 1, year); 
  
    // i --> Iterate through all the months 
    // j --> Iterate through all the days of the 
    //       month - i 
    for (int i = 0; i < 12; i++) 
    { 
        days = numberOfDays (i, year); 
  
        // Print the current month name 
        printf("\n  ------------%s-------------\n", 
               getMonthName (i).c_str()); 
  
        // Print the columns 
        printf("  Sun  Mon  Tue  Wed  Thu  Fri  Sat\n"); 
  
        // Print appropriate spaces 
        int k; 
        for (k = 0; k < current; k++) 
            printf("     "); 
  
        for (int j = 1; j <= days; j++) 
        { 
            printf("%5d", j); 
  
            if (++k > 6) 
            { 
                k = 0; 
                printf("\n"); 
            } 
        } 
  
        if (k) 
            printf("\n"); 
  
        
    } 
  
    return; 
} 
  
// Driver Program to check above funtions 
int main() 
{ 
    int year = 2016; 
    printCalendar(year); 
  
    return (0); 
} 

There is a red underline on line 77...
Last edited on
There is a red underline on line 77...
You should say whether this is a compiler error or just a warning. It should say something when you hover over the red underline, and it should also show a list of errors/warnings in your code. Those are important; part of programming is learning how to reason about what an error message is telling you.
 In function 'int numberOfDays(int, int)':
77:1: warning: control reaches end of non-void function [-Wreturn-type]


The issue is that the compiler is not smart enough to know that only numbers 0 through 11 are valid inputs to the numberOfDays function.

The function does not return if monthNumber < 0 or monthNumber > 11.

At the end of your function, just put something like
return 0; to make the compiler happy.
Last edited on
closed account (oG8qGNh0)
I have changed the code up a bit... In the bottom of the calendar in output, it says "exited, segmentation fault" when it should be saying

Press
- n for next year
- p for previous year
- e for exit

How can I change the code so it can show that result?

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
#include <iostream>
#include <iomanip>
#include <time.h>
using namespace std;
void printCalender (int year)
{

int t[] = { 0 , 3 , 2 , 5 , 0 , 3 , 5 , 1 , 4 , 6 , 2 , 4 };
int mDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
string monthList[] = {"January", "February", "March", "April", "May", "June", "July", "August" "September", "October", "November", "December"};

cout <<" ---------------------------------"<<endl;
cout <<"          Calender - "<<year<<endl;
cout <<" ---------------------------------"<<endl;
int days;
int current;
int y = year - 1;
current = (y + y/4 - y/100 + y/400 + t[0] + 1) % 7;
for (int i = 0; i < 12; i++)
{
if( i==1 ) 
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
days = 29;
else 
days = mDays [i];
else days = mDays [i];
cout<<endl<<" ------------"<<monthList[i]<<"------------"<<endl;
cout<<" Sun Mon Tue Wed Thu Fri Sat"<<endl;
int k;
for (k = 0; k < current; k++)
cout<<"    ";
for (int j = 1; j <= days; j++)
{
k++;
cout<<setw(5)<<j;
if (k > 6)
{
k = 0;
cout<<endl;
}
}
if (k)
cout<<endl;
current = k;
}
return;
}
int main () {
system ("cls");
time_t ttime = time(0);
tm *local_time = localtime (&ttime);
int year = 1900 + local_time->tm_year;
char option;
do{
system ("cls");
printCalender (year);
cout<<endl<<endl;
cout<<"Press "<<endl;
cout<<"-n for next year"<<endl;
cout<<"-p for previous year"<<endl;
cout<<"-e for exit"<<endl;
option = getchar();
switch(option){
case 'n':
year++;
break;
case 'p':
year--;
break;
}
}while(option!='e' && option!='E');
return 0;
}
You have a comma missing after August. monthlist has only 11 entries!

You also have a display formatting issue - but that's easy to fix.

When using an array with several elements, it's easy to get a typing error. To check that there are the right number of elements:

1
2
3
4
5
#include <iterator>  //At the top

// after string monthlist

static_assert(size(t) == 12 && size(mDays) == 12 && size(monthList) == 12);


If the number of elemenst in the arrays isn't 12 then you'll get a compiler error. Try it before you fix the problem with monthlist.
Last edited on
closed account (oG8qGNh0)
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
#include <iostream>
#include <iomanip>
#include <iterator> 
#include <time.h>
using namespace std;
void printCalender (int year)
{

int t[] = { 0 , 3 , 2 , 5 , 0 , 3 , 5 , 1 , 4 , 6 , 2 , 4 };
int mDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
string monthList[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
static_assert(size(t) == 12 && size(mDays) == 12 && size(monthList) == 12);
cout <<" ---------------------------------"<<endl;
cout <<"          Calender - "<<year<<endl;
cout <<" ---------------------------------"<<endl;
int days;
int current;
int y = year - 1;
current = (y + y/4 - y/100 + y/400 + t[0] + 1) % 7;
for (int i = 0; i < 12; i++)
{
if( i==1 ) 
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
days = 29;
else 
days = mDays [i];
else days = mDays [i];
cout<<endl<<" ------------"<<monthList[i]<<"------------"<<endl;
cout<<" Sun Mon Tue Wed Thu Fri Sat"<<endl;
int k;
for (k = 0; k < current; k++)
cout<<"    ";
for (int j = 1; j <= days; j++)
{
k++;
cout<<setw(5)<<j;
if (k > 6)
{
k = 0;
cout<<endl;
}
}
if (k)
cout<<endl;
current = k;
}
return;
}
int main () {
system ("cls");
time_t ttime = time(0);
tm *local_time = localtime (&ttime);
int year = 1900 + local_time->tm_year;
char option;
do{
system ("cls");
printCalender (year);
cout<<endl<<endl;
cout<<"Press "<<endl;
cout<<"-n for next year"<<endl;
cout<<"-p for previous year"<<endl;
cout<<"-e for exit"<<endl;
option = getchar();
switch(option){
case 'n':
year++;
break;
case 'p':
year--;
break;
}
}while(option!='e' && option!='E');
return 0;
}


Everything worked! Thanks!
@naveenmmenon,

Your first post was nicely formatted. Your latest 2 posts have poorly-formatted code (no indentation). Those posts are much more difficult to read than your first.

Do you know what you did differently the 2nd and 3rd times? If you do, try to avoid it in future posts.

Generally, put the code tags if first, and then copy & paste your code into them.
Everything worked! Thanks!


Just the formatting of the headers/first row to fix now.
closed account (oG8qGNh0)
wdym seeplus?

------------December------------
Sun Mon Tue Wed Thu Fri Sat
           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


The days header doesn't align with day numbers - and the first line of the days doesn't align with the rest of the lines. I would have thought it should display as:


------------December---------------
 Sun  Mon  Tue  Wed  Thu  Fri  Sat
             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

Last edited on
closed account (oG8qGNh0)
How would I make that even?
Adjust the formatting.

Change:

 
cout<<" Sun Mon Tue Wed Thu Fri Sat"<<endl;


and

 
cout<<"    ";

Last edited on
When you lift code from the internet, you should try to understand what it's doing and how to apply it. Your printCalender() function doesn't need the t array as you only need the day for 1 January.

Also this function can be much simplified.

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
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;

inline bool isleap(int year)
{
	return (year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0));
}

void printCalender(int year)
{
	constexpr int mDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	const static string monthList[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

	static_assert(size(mDays) == 12 && size(monthList) == 12);

	cout << " ---------------------------------" << endl;
	cout << "          Calender - " << year << endl;
	cout << " ---------------------------------" << endl;

	for (int i = 0, k = (year + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400) % 7; i < 12; ++i) {
		cout << "\n ------------" << monthList[i] << "------------\n";
		cout << "  Sun  Mon  Tue  Wed  Thu  Fri  Sat\n";
		cout << setw(k * 5) << "";

		for (int j = 1, days = mDays[i] + (i == 1 && isleap(year)); j <= days; ++j) {
			cout << setw(5) << j;

			if ((k = (k + 1) % 7) == 0)
				cout << '\n';
		}

		if (k != 0)
			cout << '\n';
	}
}

int main() {
	const time_t ttime {time(0)};

	int year {1900 + localtime(&ttime)->tm_year};
	char option {};

	do {
		system("cls");
		printCalender(year);

		cout << endl << endl;
		cout << "Press " << endl;
		cout << "-n for next year" << endl;
		cout << "-p for previous year" << endl;
		cout << "-e for exit" << endl;

		switch (option = (char)getchar()) {
			case 'n':
				++year;
				break;

			case 'p':
				--year;
				break;
		}
	} while (option != 'e' && option != 'E');
}


Also, as you're using repl.it (still?), you'll find that system("cls") doesn't work. You'll get the error message "bash: cls: command not found". The bash command to clear the screen is clear. cls is MS.

PS For those mathematically inclined and think about simplifying the initial value of k using algebraic manipulation - don't! The existing formula is based upon int division!!
Last edited on
closed account (oG8qGNh0)
But like step by step how would you explain this?

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
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;

inline bool isleap(int year)
{
return (year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0));
}

void printCalender(int year)
{
constexpr int mDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const static string monthList[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

static_assert(size(mDays) == 12 && size(monthList) == 12);

cout << " ---------------------------------" << endl;
cout << "          Calender - " << year << endl;
cout << " ---------------------------------" << endl;

for (int i = 0, k = (year + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400) % 7; i < 12; ++i) {
cout << "\n ------------" << monthList[i] << "------------\n";
cout << "  Sun  Mon  Tue  Wed  Thu  Fri  Sat\n";
cout << setw(k * 5) << "";

for (int j = 1, days = mDays[i] + (i == 1 && isleap(year)); j <= days; ++j) {
cout << setw(5) << j;

if ((k = (k + 1) % 7) == 0)
cout << '\n';
}

if (k != 0)
cout << '\n';
}
}

int main() {
const time_t ttime {time(0)};

int year {1900 + localtime(&ttime)->tm_year};
char option {};

do {
system("cls");
printCalender(year);

cout << endl << endl;
cout << "Press " << endl;
cout << "-n for next year" << endl;
cout << "-p for previous year" << endl;
cout << "-e for exit" << endl;

switch (option = (char)getchar()) {
case 'n':
++year;
break;

case 'p':
--year;
break;
}
} while (option != 'e' && option != 'E');
}
What happened to using code tags so that the code is displayed properly formatted?

What lines don't you understand?

static_assert() just checks at compile time that the given expression is true. if it isn't it generates a compiler error. As there are 12 months in the year, this simply checks that the arrays mDays and monthList both have 12 entries.


closed account (oG8qGNh0)
my teacher says that I need to make a recording of explain each line of code. She says that sh did not teach a lot of these things. for ex. static_assert(), inline bool isleap(int year), const static string monthList[], for (int j = 1, days = mDays[i] + (i == 1 && isleap(year)); j <= days; ++j) {cout << setw(5) << j;, etc.
closed account (oG8qGNh0)
wait and i did use the code tag. Isn't it properly formatted?
Wait, you actually took that code that was meant to serve as illustration for what to do, and submitted it as if you wrote it? That's plagiarism.

Relatedly, @seeplus, this is why it's a bad idea to offer full code solutions.

EDIT: Didn't realize there was a post asking about the code tags.
Notice how there's no indentation? That indentation actually really helps programmers read code. That's what the complaints are about.

-Albatross
Last edited on
She says that she did not teach a lot of these things.


She's wise to that you're getting help! So submit your own program from previous - which was obtained from another internet site (function dayNumber() et al where you don't need array t here).

Apart from the static_assert (explained above), there shouldn't be much else that you shouldn't understand. Possibly static (which your original program also had from the copied code)? - which simply means in this context that the variable initialisation is only done once the first time the function is used. After the first time the value of the variable is the same as it was the previous time the function was used. As monthList doesn't change, this ensures that it is initialised only once - which helps run-time performance.

constexpr means initialise the variable at compile time, if possible, rather than run-time. Again, it helps run-time performance.

Everything else you should know - as it was based upon your code. I just 'simplified' it.
Last edited on

my teacher says that I need to make a recording of explain each line of code. She says that sh did not teach a lot of these things. for ex. static_assert(), inline bool isleap(int year), const static string monthList[], for (int j = 1, days = mDays[i] + (i == 1 && isleap(year)); j <= days; ++j) {cout << setw(5) << j;, etc.


this is an excellent teacher, by the way. A lot of people come here and tell us they can't do this or that because they lose points for doing anything but spewing back what few little things the teacher said in class rather than learning. Asking you to explain what you did and allowing it is AWESOME. So go do it! (a recording seems dumb, though: this is why we can haz comments. listening to someone talk takes 10 to 20 times longer than reading it). All she really wants it to know that you did it and understand it, not a copy from the web etc.
Last edited on
But it's hard to make a 5 minute spoken explanation that isn't all 'umm, err, no, lemme think" unless you do actually understand what you're talking about(*).

A written explanation doesn't show how long it took, or how many times the backspace key was pressed, or indeed where the information was copy/pasted from.

(*)excepting politicians.
Pages: 12