6
\$\begingroup\$

There is no error checking in day_of_year or month_day. remedy this defect.

Here is the solution:

int day_of_year(unsigned int year, unsigned int month, int day) {
    int leap, i;

    leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));

    if(((month >= 1) && (month <= 12)) && ((day >= 1) && (day <= daytab[leap][month]))) {
        for(i = 1; i < month; i++) {
            day += daytab[leap][i];
        }

        return day;
    }

    return -1;

}

void month_day(unsigned int year, unsigned int yearday, int *pmonth, int *pday) {
    int leap, i;

    leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
    if((leap == 1 && (yearday >= 1 && yearday <= 366)) || (leap == 0 && (yearday >= 1 && yearday <= 366))) {

        for(i = 1; yearday > daytab[leap][i]; i++) {
          yearday -= daytab[leap][i];
        }
        *pday = yearday;
        *pmonth = i;
    }
    else {
        printf("error: the yearday is invalid");
    }
}

In the day_of_year's case I have to check if the yearday is a valide one. 1 <= yearday <= (365 || 366). I changed the parameters type to unsigned, because a day can't be negative nor a year.

In the month_day's case I check if the month is a valid one, it should be 1 <= month <= 12. After this, I check if the day belongs to a valid interval.

This exercise can be found in K&R2 at page 126.

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$
  1. Incorrect yearday limit

    // if((leap == 1 ... || (leap == 0 && (yearday >= 1 && yearday <= 366))) {
    if((leap == 1 ... || (leap == 0 && (yearday >= 1 && yearday <= 365))) {
    //                                                             365  
    
  2. month_day() and day_of_year() should use consistent types for month. Suggest int for both.

    // int day_of_year(unsigned int year, unsigned int month, int day) {
    // void month_day(unsigned int year, unsigned int yearday, int *pmonth, int *pday) {
    int day_of_year(unsigned int year,         int month, int day) {
    
  3. month_day() and day_of_year() should use consistent types for yearday. Suggest int for both.

    // int day_of_year(unsigned int year, unsigned int month, int day) {
    // void month_day(unsigned int year, unsigned int yearday, int *pmonth, int *pday) {
    int day_of_year(unsigned int year, int month, int day) {
    void month_day(unsigned int year, int yearday, int *pmonth, int *pday) {
    
  4. Leap year calculation leap = ((year... is good back to 1583. For years 4 to 1582 it is leap = (year % 4 == 0); 1582 has other complications. Before 4 has complications.

  5. Suggest month_day() return int to indicate success or failure.

\$\endgroup\$
2
  • \$\begingroup\$ if yearday will be an int the user may pass negative values. Should I modify my function such that it will handle a negativeyearday? \$\endgroup\$
    – cristid9
    Commented Feb 10, 2014 at 20:22
  • 1
    \$\begingroup\$ @Ionut Grt. Suggest that a negative yearday is treated like 0 or 367+. Looks like code yearday >= 1 catches that already. \$\endgroup\$
    – chux
    Commented Feb 10, 2014 at 21:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.