There is no error-checking in day_of_year or month_day. Remedy this defect.
Solution by Lars Wirzenius
/*
* A solution to exercise 5-8 in K&R2, page 112:
*
* There is no error checking in day_of_year or month_day. Remedy
* this defect.
*
* The error to check for is invalid argument values. That is simple, what's
* hard is deciding what to do in case of error. In the real world, I would
* use the assert macro from assert.h, but in this solution I take the
* approach of returning -1 instead. This is more work for the caller, of
* course.
*
* I have selected the year 1752 as the lowest allowed year, because that
* is when Great Britain switched to the Gregorian calendar, and the leap
* year validation is valid only for the Gregorian calendar.
*
* Lars Wirzenius <liw@iki.fi>
*/
#include <stdio.h>
static char daytab[2][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},
};
/* day_of_year: set day of year from month & day */
int day_of_year(int year, int month, int day)
{
int i, leap;
if (year < 1752 || month < 1 || month > 12 || day < 1)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if (day > daytab[leap][month])
return -1;
for (i = 1; i < month; i++)
day += daytab[leap][i];
return day;
}
/* month_day: set month, day from day of year */
int month_day(int year, int yearday, int *pmonth, int *pday)
{
int i, leap;
if (year < 1752 || yearday < 1)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if ((leap && yearday > 366) || (!leap && yearday > 365))
return -1;
for (i = 1; yearday > daytab[leap][i]; i++)
yearday -= daytab[leap][i];
*pmonth = i;
*pday = yearday;
return 0;
}
/* main: test day_of_year and month_day */
int main(void)
{
int year, month, day, yearday;
for (year = 1970; year <= 2000; ++year) {
for (yearday = 1; yearday < 366; ++yearday) {
if (month_day(year, yearday, &month, &day) == -1) {
printf("month_day failed: %d %d\n",
year, yearday);
} else if (day_of_year(year, month, day) != yearday) {
printf("bad result: %d %d\n", year, yearday);
printf("month = %d, day = %d\n", month, day);
}
}
}
return 0;
}
menonsahab's
#include <stdio.h>
#include <stdlib.h>
static char daytab[2][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}
};
int day_of_year(int year, int month, int day)
{
if( year < 1752 )
return -1;
int i, leap;
leap = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if( !((month >= 1 && month <= 12) && (day >= 1 && day <= daytab[leap][month])) )
return -1;
for(i = 1; i < month; i++)
{
day += daytab[leap][i];
}
return day;
}
void month_day(int year, int yearday, int *pmonth, int *pday)
{
if( year < 1752 )
{
*pmonth = *pday = -1;
return;
}
int i, leap;
leap = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if( !(yearday >= 1 && yearday <= (leap ? 366 : 365)))
{
*pmonth = *pday = -1;
return;
}
for(i = 1; yearday > daytab[leap][i]; i++)
yearday -= daytab[leap][i];
*pmonth = i;
*pday = yearday;
}
int main()
{
int month, day, year, yearday, retval;
/******************************* Case 1 *****************************/
printf("Case 1:\n");
year = -2017;
month = 11;
day = 22;
yearday = 326;
retval = day_of_year(year, month, day);
if(retval == -1)
printf("Incorrect input\n");
else
printf("%d %d %d <---> %d %d\n", year, month, day, year, retval);
month_day(year, yearday, &month, &day);
if(month == -1 && day == -1)
printf("Incorrect input\n");
else
printf("%d %d <---> %d %d %d\n", year, yearday, year, month, day);
printf("\n");
/*********************************************************************/
/******************************* Case 2 *****************************/
printf("Case 2:\n");
year = 2017;
month = -11;
day = 22;
yearday = 326;
retval = day_of_year(year, month, day);
if(retval == -1)
printf("Incorrect input\n");
else
printf("%d %d %d <---> %d %d\n", year, month, day, year, retval);
month_day(year, yearday, &month, &day);
if(month == -1 && day == -1)
printf("Incorrect input\n");
else
printf("%d %d <---> %d %d %d\n", year, yearday, year, month, day);
printf("\n");
/*********************************************************************/
/******************************* Case 3 *****************************/
printf("Case 3:\n");
year = 2017;
month = 11;
day = -22;
yearday = 326;
retval = day_of_year(year, month, day);
if(retval == -1)
printf("Incorrect input\n");
else
printf("%d %d %d <---> %d %d\n", year, month, day, year, retval);
month_day(year, yearday, &month, &day);
if(month == -1 && day == -1)
printf("Incorrect input\n");
else
printf("%d %d <---> %d %d %d\n", year, yearday, year, month, day);
printf("\n");
/*********************************************************************/
/******************************* Case 4 *****************************/
printf("Case 4:\n");
year = 2017;
month = 11;
day = 22;
yearday = -326;
retval = day_of_year(year, month, day);
if(retval == -1)
printf("Incorrect input\n");
else
printf("%d %d %d <---> %d %d\n", year, month, day, year, retval);
month_day(year, yearday, &month, &day);
if(month == -1 && day == -1)
printf("Incorrect input\n");
else
printf("%d %d <---> %d %d %d\n", year, yearday, year, month, day);
printf("\n");
/*********************************************************************/
/******************************* Case 5 *****************************/
printf("Case 5:\n");
year = 2017;
month = 11;
day = 22;
yearday = 326;
retval = day_of_year(year, month, day);
if(retval == -1)
printf("Incorrect input\n");
else
printf("%d %d %d <---> %d %d\n", year, month, day, year, retval);
month_day(year, yearday, &month, &day);
if(month == -1 && day == -1)
printf("Incorrect input\n");
else
printf("%d %d <---> %d %d %d\n", year, yearday, year, month, day);
printf("\n");
/*********************************************************************/
return 0;
}
/*
The output of the above program is:
Case 1:
Incorrect input
Incorrect input
Case 2:
Incorrect input
2017 326 <---> 2017 11 22
Case 3:
Incorrect input
2017 326 <---> 2017 11 22
Case 4:
2017 11 22 <---> 2017 326
Incorrect input
Case 5:
2017 11 22 <---> 2017 326
2017 326 <---> 2017 11 22
*/
'The C Programming Language' 카테고리의 다른 글
Chapter 5 - Pointers and Arrays 10 (0) | 2009.03.27 |
---|---|
Chapter 5 - Pointers and Arrays 9 (0) | 2009.03.27 |
Chapter 5 - Pointers and Arrays 7 (0) | 2009.03.27 |
Chapter 5 - Pointers and Arrays 6 (0) | 2009.03.27 |
Chapter 5 - Pointers and Arrays 5 (0) | 2009.03.27 |