Exercise 5-8 (Calendar)
Chapter_5 Exercise_5-7 | Exercise_5-9 |
Exercise 5-8 K&R, p. 112
Exercise 5-8. There is no error checking in day_of_year() or month_day(). Remedy this defect.
days.c K&R, p. 111 download
#include <stdio.h> // for printf(), scanf()
static char daytab[2][13] = // daytab[][13] =
{
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
}; // don't forget semicolon
static char *monthtab[13] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; // don't forget semicolon
// get day of year from year (leap or not), month, day of month
int day_of_year(int year, int month, int day);
// set month and day of month from year (leap or not) and day of that year
int month_day(int year, int yearday, int *pmonth, int *pday); // return error code
int main()
{
int year, month, day, yearday, error;
printf("Year: ");
scanf("%d", &year);
printf("Yearday (1 ... 365 / 366): "); // for leap years
scanf("%d", &yearday);
error = month_day(year, yearday, &month, &day);
if (error) {return 1;} // signal error
printf("year %d, yearday %d: month %d (%s), day %d\n",
year, yearday, month, monthtab[month], day);
printf("Year: ");
scanf("%d", &year);
printf("Month (1 ... 12): ");
scanf("%d", &month);
printf("Day (1 ... 28 / 29 / 30 / 31): ");
scanf("%d", &day);
yearday = day_of_year(year, month, day);
if (yearday == 0) // error
{return 1;} // signal error
printf("year %d, yearday %d: month %d (%s), day %d\n",
year, yearday, month, monthtab[month], day);
return 0;
}
int leap_year (int year); // leap year?
// get day of year from year (leap or not), month, day of month
int day_of_year(int year, int month, int day)
{
if (month <= 0 || day <= 0)
{
printf("Month and Day of month > 0\n");
return 0; // signal error
}
if (month > 12)
{
printf("1 <= month <= 12\n");
return 0; // signal error
}
if (day > 31)
{
printf("1 <= day of month <= 28 / 29 / 30 / 31\n");
return 0; // signal error
}
int i, leap = leap_year(year);
if (day > daytab[leap][month])
{
if (month == 2 && day == 29)
{
printf("1 <= day of month <= %d for month %d (%s), year %d\n",
daytab[leap][month], month, monthtab[month], year);
}
else if (month == 2 && day > 29)
{
printf("1 <= day of month <= 28 / 29 for month %d (%s)\n",
month, monthtab[month]);
}
else
{
printf("1 <= day of month <= %d for month %d (%s)\n",
daytab[leap][month], month, monthtab[month]);
}
return 0; // signal error
}
for (i = 1; i < month; i++)
{
day += daytab[leap][i];
}
return day;
}
// set month and day of month from year (leap or not) and day of that year
int month_day(int year, int yearday, int *pmonth, int *pday) // return error code
{
if (yearday <= 0)
{
printf("Day of the year > 0\n");
return 1; // signal error
}
if (yearday > 366)
{
printf("Day of the year <= 365 or 366 for leap years\n");
return 1; // signal error
}
int i, leap = leap_year(year);
if (!leap && yearday == 366)
{
printf("Day of the year == 366 only for leap years\n");
return 1; // signal error
}
for (i = 1; yearday > daytab[leap][i]; i++)
{
yearday -= daytab[leap][i];
}
*pmonth = i;
*pday = yearday;
return 0; // no error
}
int leap_year (int year) // leap year?
{
return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
}
/*
gcc days.c -o days
./days
Year: 2013
Yearday (1 ... 365 / 366): 0
Day of the year > 0
./days
Year: 2013
Yearday (1 ... 365 / 366): 367
Day of the year <= 365 or 366 for leap years
./days
Year: 2013
Yearday (1 ... 365 / 366): 366
Day of the year == 366 only for leap years
./days
Year: 2013
Yearday (1 ... 365 / 366): 365
year 2013, year-day 365: month 12 (Dec), day 31
Year: 2013
Month (1 ... 12): 0
Day (1 ... 28 / 29 / 30 / 31): 1
Month and Day of month > 0
./days
Year: 2014
Yearday (1 ... 365 / 366): 365
year 2014, year-day 365: month 12 (Dec), day 31
Year: 2015
Month (1 ... 12): 31
Day (1 ... 28 / 29 / 30 / 31): 1
1 <= month <= 12
./days
Year: 2012
Yearday (1 ... 365 / 366): 366
year 2012, yearday 366: month 12 (Dec), day 31
Year: 2012
Month (1 ... 12): 12
Day (1 ... 28 / 29 / 30 / 31): 31
year 2012, yearday 366: month 12 (Dec), day 31
./days
Year: 2015
Yearday (1 ... 365 / 366): 1
year 2015, year-day 1: month 1 (Jan), day 1
Year: 2012
Month (1 ... 12): 12
Day (1 ... 28 / 29 / 30 / 31): 0
Month and Day of month > 0
./days
Year: 2012
Yearday (1 ... 365 / 366): 60
year 2012, year-day 60: month 2 (Feb), day 29
Year: 2012
Month (1 ... 12): 10
Day (1 ... 28 / 29 / 30 / 31): 32
1 <= day of month <= 28 / 29 / 30 / 31
./days
Year: 2012
Yearday (1 ... 365 / 366): 60
year 2012, yearday 60: month 2 (Feb), day 29
Year: 2012
Month (1 ... 12): 10
Day (1 ... 28 / 29 / 30 / 31): 31
year 2012, yearday 305: month 10 (Oct), day 31
./days
Year: 2012
Yearday (1 ... 365 / 366): 60
year 2012, yearday 60: month 2 (Feb), day 29
Year: 2012
Month (1 ... 12): 9
Day (1 ... 28 / 29 / 30 / 31): 31
1 <= day of month <= 30 for month 9 (Sep)
./days
Year: 2012
Yearday (1 ... 365 / 366): 60
year 2012, yearday 60: month 2 (Feb), day 29
Year: 2012
Month (1 ... 12): 9
Day (1 ... 28 / 29 / 30 / 31): 30
year 2012, yearday 274: month 9 (Sep), day 30
./days
Year: 2011
Yearday (1 ... 365 / 366): 60
year 2011, yearday 60: month 3 (Mar), day 1
Year: 2011
Month (1 ... 12): 2
Day (1 ... 28 / 29 / 30 / 31): 30
1 <= day of month <= 28 / 29 for month 2 (Feb)
./days
Year: 2011
Yearday (1 ... 365 / 366): 60
year 2011, yearday 60: month 3 (Mar), day 1
Year: 2011
Month (1 ... 12): 2
Day (1 ... 28 / 29 / 30 / 31): 29
1 <= day of month <= 28 for month 2 (Feb), year 2011
./days
Year: 2011
Yearday (1 ... 365 / 366): 60
year 2011, yearday 60: month 3 (Mar), day 1
Year: 2011
Month (1 ... 12): 2
Day (1 ... 28 / 29 / 30 / 31): 28
year 2011, yearday 59: month 2 (Feb), day 28
./days
Year: 1988
Yearday (1 ... 365 / 366): 60
year 1988, yearday 60: month 2 (Feb), day 29
Year: 1988
Month (1 ... 12): 2
Day (1 ... 28 / 29 / 30 / 31): 29
year 1988, yearday 60: month 2 (Feb), day 29
*/
Chapter_5 Exercise_5-7 | BACK_TO_TOP | Exercise_5-9 |
Comments
Post a Comment