Reputation: 50
#include <stdio.h>
#include <math.h>
.
.
.
void calendar(int year, int month){
int days, wd;
puts("===================================================");
printf(" %c%c%c/%d\n",month_str[month][0],month_str[month][1],month_str[month][2],year);
puts("\nSUN MON TUE WED THU FRI SAT");
if(month == 2)
{
if(isLeap(year)==1)
days = 29;
if(isLeap(year)==0)
days = 28;
}
else
days = days_in_months[month];
// i need to correct this part
//print dates
for (int d = 1; d <= 1 + weekDay(year,month,d) * 5; d++ )
{
printf(" ");
}
for (int i = 1; i <=days; i++)
{
wd = weekDay(year,month, i);
printf("%.2d",i);
if ((wd+1) % 7 == 0)
printf("\n");
else
printf(" ");
}
puts("\n===================================================");
}
When i input 2/2015 it gives infinity loop.(Now i don't have problems with infinity loop)
Example: Input: 2 2020 | Output:
===================================================
FEB/2020
SUN MON TUE WED THU FRI SAT
-- -- -- -- -- -- 01
02 03 04 05 06 07 08
09 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
===================================================
Input: 02 2015 | Output:
===================================================
APR/2020
SUN MON TUE WED THU FRI SAT
-- -- -- 01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 -- --
===================================================
I have problems only with output
More details,More details,More details,More details,More details,More details,More details,More details,More details,More details,More details
Upvotes: 0
Views: 97
Reputation: 84599
Unless I'm misunderstanding something, the only thing you are worried about is how to align the first partial week of numbers under the weekday headings. Since the first day of every month is the 1st, you can just concentrate on weekDay(year,month,1)
.
Additionally, since the days are all separated by 8-characters (one normal tab
width), you can simply insert 8-spaces for each weekday offset. So you essentially need to pad the first day for a total number of spaces:
padding = weekDay(year,month,1) * 8;
That allows you to eliminate your loop and simply use a field-width modifier that is set by padding
as the first argument to printf
when outputting a space, e.g.
int days, wd, padding; /* add padding variable */
...
// for (int d = 1; d <= 1 + weekDay(year,month,d) * 5; d++)
// {
// printf(" ");
// }
if ((padding = weekDay(year,month,1) * 8))
printf ("%*s", padding, " ");
Or after computing the padding
, you could simply loop that number of times outputting spaces, e.g.
padding = weekDay(year,month,1) * 8;
while (padding--)
putchar (' ');
Same result either way.
Example Use/Output
That appears to do what it is you are attempting, e.g.
For March, 2020
$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
MAR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
===================================================
For April, 2020:
$ ./bin/calendar
enter mm yyyy : 4 2020
===================================================
APR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
===================================================
For May, 2020:
$ ./bin/calendar
enter mm yyyy : 5 2020
===================================================
MAY/20
SUN MON TUE WED THU FRI SAT
01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
===================================================
Adding Placeholders At Beginning & End
If you want to add the "-- "
placeholders for empty dates, then to add placeholders at the beginning you could just loop that many times padding with the full string, e.g.
padding = weekDay(year,month,1);
while (padding--)
fputs ("-- ", stdout);
And at the end, recalculate the padding from the last day to the end, e.g.
padding = 7 - weekDay(year,month,days) - 1;
while (padding--)
fputs ("-- ", stdout);
puts("\n===================================================");
Example Use/Output
With the placeholder, you would have:
Feb, 2020:
$ ./bin/calendar
enter mm yyyy : 2 2020
===================================================
FEB/20
SUN MON TUE WED THU FRI SAT
-- -- 01 02 03 04 05
06 07 08 09 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 -- -- -- --
===================================================
March, 2020:
$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
MAR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 -- -- -- --
===================================================
April, 2020:
$ ./bin/calendar
enter mm yyyy : 4 2020
===================================================
APR/20
SUN MON TUE WED THU FRI SAT
-- -- -- 01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 -- --
===================================================
Which verifying with my calendar appears correct. The full code I used to test was:
(updated: to fix weekDay()
calculation)
#include <stdio.h>
#include <math.h>
const char weekday_str[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
const char month_str[13][4] = {"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN","JUL",
"AGO", "SEP", "OCT", "NOV", "DEC"};
const int days_in_months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int weekDay (int yr, int mh, int d)
{
int y, c, m, w;
if (mh == 1 || mh == 2)
yr--;
y = yr % 100;
c = (yr - y) / 100;
if (mh == 1 || mh == 2)
m = mh + 10;
else if (mh <= 12 || mh >= 3)
m = mh - 2;
w = ((d + floor(2.6*m - 0.2) + y + floor(0.25*y) + floor(0.25*c) - 2*c ));
w = w % 7;
if(w < 0)
w += 7;
return w;
}
int isLeap (int year)
{
if (year%4 != 0)
return 0;
else if (year%100 != 0)
return 1;
else if (year%400 != 0)
return 0;
else
return 1;
}
void calendar (int year, int month)
{
int days, wd, padding;
puts ("===================================================");
printf (" %c%c%c/%d\n",
month_str[month][0],month_str[month][1],month_str[month][2],year);
puts ("\nSUN MON TUE WED THU FRI SAT");
if (month == 2) {
if (isLeap(year) == 1)
days = 29;
if (isLeap(year) == 0)
days = 28;
}
else
days = days_in_months[month];
padding = weekDay(year,month,1);
while (padding--)
fputs ("-- ", stdout);
for (int i = 0; i < days; i++) {
wd = weekDay(year,month, i + 1);
printf("%.2d", i + 1);
if ((wd+1) % 7 == 0)
printf("\n");
else
printf(" ");
}
padding = 7 - weekDay(year,month,days) - 1;
while (padding--)
fputs ("-- ", stdout);
puts("\n===================================================");
}
int main (void) {
int mm, yyyy;
fputs ("enter mm yyyy : ", stdout);
if (scanf ("%d %*c%d", &mm, &yyyy) != 2) {
fputs ("error: invalid format.\n", stderr);
return 1;
}
calendar (yyyy, mm);
}
Invalid weekDay()
Calculation
The problem with your calendar for Jan or Feb is the incorrect adjustment of m = mh;
You have:
if (mh == 1 || mh == 2)
m = mh + 10;
if (mh <= 12 || mh >= 3)
m = mh - 2;
You need:
if (mh == 1 || mh == 2)
m = mh + 10;
else if (mh <= 12 || mh >= 3)
m = mh - 2;
Reason: after you adjust Jan
or Feb
as m = mh + 10;
you check again, if (mh <= 12 || mh >= 3)
which is now true since you just added + 10
, so you then do m = mh - 2
resulting in the wrong value for mh
.
Example Use/Output
For Jan, 2020
$ ./bin/calendar
enter mm yyyy : 1 2020
===================================================
JAN/20
SUN MON TUE WED THU FRI SAT
-- -- -- 01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 --
===================================================
For Feb, 2020
$ ./bin/calendar
enter mm yyyy : 2 2020
===================================================
FEB/20
SUN MON TUE WED THU FRI SAT
-- -- -- -- -- -- 01
02 03 04 05 06 07 08
09 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
===================================================
For March, 2020
$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
MAR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 -- -- -- --
===================================================
Let me know if you have any questions.
Upvotes: 2