HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Program that tells if a date is valid in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
programdatetellsthatvalid

Problem

I'm reading a book about C programming, at the end of each chapter it has some training exercise and one of them was to make a program that tells if a date is valid or not, the code below is what I did and I would like to know if it can be improved?

#include 

int main(){
int dd,mm,yy;

printf("write a date(day/month/year):");
scanf("%d/%d/%d",&dd,&mm,&yy);

int bissextile=(yy%4==0)?1:0;

if (dd>31 || dd12 || mm<1)
    printf("Invalid date.\n");
    else
        if((mm==2 && dd<30 && bissextile) || (mm==2 && dd<29 && bissextile==0))
            printf("valid date.\n");
            else
                if((mm==4 || mm==6 || mm==9 || mm==11)&& dd<31)
                    printf("valid date.\n");
                    else
                        if(dd<31 && mm!=2)
                            printf("valid date.\n");
                            else
                                printf("Invalid date.\n");
}

Solution

Validation is a specific task, distinct from receiving input, so it deserves to have its own function.

The code suffers from excessive nesting, which could be improved by putting else if at the same indentation level. However, another problem is that some of the checks are affirmative and some of them are negative, which makes the code harder to follow.

Since the validation depends mostly on the month, I'd write it this way, with a switch:

int isValid(int dd, int mm, int yy) {
    if (dd <= 0) return 0;
    switch (mm) {
      case 1: case 3: case 5: case 7:
      case 8: case 10: case 12:
        return dd <= 31;
      case 4: case 6: case 9: case 11:
        return dd <= 30;
      case 2:
        return dd <= 28 + (yy % 4 == 0);
      default:
        return 0;  /* invalid month */
    }
}


Then, in main():

if ( 3 == scanf("%d/%d/%d",&dd,&mm,&yy) &&
     isValid(dd, mm, yy) ) {
    puts("Valid date");
} else {
    puts("Invalid date");
}


Note that validating the return value from scanf() is important too.

The code doesn't handle the Gregorian correction properly, such as for year 1900.

Code Snippets

int isValid(int dd, int mm, int yy) {
    if (dd <= 0) return 0;
    switch (mm) {
      case 1: case 3: case 5: case 7:
      case 8: case 10: case 12:
        return dd <= 31;
      case 4: case 6: case 9: case 11:
        return dd <= 30;
      case 2:
        return dd <= 28 + (yy % 4 == 0);
      default:
        return 0;  /* invalid month */
    }
}
if ( 3 == scanf("%d/%d/%d",&dd,&mm,&yy) &&
     isValid(dd, mm, yy) ) {
    puts("Valid date");
} else {
    puts("Invalid date");
}

Context

StackExchange Code Review Q#104685, answer score: 9

Revisions (0)

No revisions yet.