0

I am trying to add code to check if the month input on the command line is in the range 1 to 12.
If it is not then print out the following error message and exit the program (Make sure that your return code is non-zero.)

$ ./dates 1 13 2019
Error -the month entered (13) is not in the proper range (1-12)
#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
   /* Names of the months */
   char *monthName[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
   /* The number of days in each month */
   int monthLength[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
   int dd = 0;
   int mm = 0;
   int yyyy = 0;
   if ( argc < 4 ) {
      printf ( "Usage: ./dates mm dd yyyy \n" );
      exit ( 1 );
   } else {
      dd = atoi ( argv[1] );
      mm = atoi ( argv[2] );
      yyyy = atoi ( argv[3] );
   }
   if (1<=mm<=12) {
      printf ( "The date is %s %02d, %04d\n", monthName[mm-1], mm, yyyy);
   } else {
      printf ("Error - the month enteres (%d) is not in the proper range ( 1-12)", mm);
   }
   return (1) ;
}

2 Answers2

3

In this statement

if (1<=mm<=12) {
.....

the expression 1<=mm<=12 will be interpreted as (1<=mm)<=12 because the associativity of operator <= is left to right. The result of 1<=mm will be boolean i.e. either true or false. Which means it will be evaluated as either 1 or 0. When 1 or 0 is compared with 12 using operator <= the result is always going to be true i.e. 1. So, the expression 1<=mm<=12 always be evaluated as true. If you input the month beyond the range of monthName array, the behavior is undefined 1) because your program will end up accessing the array monthName beyond its range. Instead, you should check month like this

if ((1 <= mm) && (mm <= 12)) {
......

More readable code would be

if ((mm >= 1) && (mm <= 12)) {
......

1) An undefined behavior includes program may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

H.S.
  • 11,654
  • 2
  • 15
  • 32
  • thanks a lot! that does make sense, but what if I wanted to add code to check if the day input on the command line is in the range 1 to the number of days in the month. If it is not then print out the following error message and exit the program. ./dates 31 4 2019 Error - you entered 31 for the day and that is not in the range (1 - 30), what should I do ? –  Sep 13 '19 at 04:07
  • @HareerThaer For checking the day range, you can modify the condition like this - `if (((mm >= 1) && (mm <= 12)) && ((dd >= 1) && (dd <= monthLength[mm - 1])))`. This will check the day range for that particular month entered by the user. Also, you have to do additional error handling for the case like month is in range but day is not etc. One more point - correct the usage output, it should be - `./dates dd mm yyyy` as in your program you are considering `argv[2]` as month and `argv[1]` as day. – H.S. Sep 13 '19 at 06:10
0

see @H.S. Answer for why the statement is invalid

#include <stdio.h>
#include <stdlib.h>
int main ( int argc, char *argv[] ) {

/* Names of the months */ char *monthName[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };

/* The number of days in each month */ int monthLength[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int dd = 0;

int mm = 0;

int yyyy = 0;

if ( argc < 4 ) {

  printf ( "Usage: ./dates mm dd yyyy \n" );

  exit ( 1 );
}

dd = atoi ( argv[1] );

mm = atoi ( argv[2] );

yyyy = atoi ( argv[3] );


if ((mm >= 1 && mm <= 12) && (dd <= 31 && dd >= 1)) {

printf ( "The date is %s %02d, %04d\n", monthName[mm-1], mm, yyyy);

} else {

printf ("Error - the month enteres (%d) is not in the proper range ( 1-12)", mm); }

return (1) ; }
DanielAaron
  • 101
  • 8