Linebacker15
Linebacker15

Reputation: 27

Counting days function in C

Here is the entirety of the code, I am still getting an invalid input every time I run the program.

#include<stdio.h>

int dpm[13]={31,28,31,30,31,30,31,31,30,31,30,31};

struct Sdate {
  int month;
  int day;
  int year;
} begin, end;

int isleapyear(int a)
{
  if((a%4==0&&a%100!=0)||a%400==0)
      return 1; 
  else
      return 0;
}


struct Sdate EnterDate(void){
  int d,m,y;
  struct Sdate A;

      printf("Enter the date(mm/dd/yyyy): ");
      scanf("%i/%i/%i", &m, &d, &y);

  printf("\n");

  A.month=m;
  A.day=d;
  A.year=y;

  return(A);
}

int  validate(void){
  if(begin.year > end.year)
      return 1; 
  if((begin.year == end.year) && (begin.month > end.month))
      return 1; 
  if((begin.year == end.year) && (begin.month == end.month) && (begin.day > end.day))
      return 1; 
  else
      return 0;
}

int count_days(void){
  int i;
  int days=0;
  int days_per_year = 365;

  if(isleapyear(begin.year)){ // first year
      if(begin.month == 1)
        days = dpm[begin.month] - begin.day + 1;
      else
        days = dpm[begin.month] - begin.day;
  }     
  else 
      days = dpm[begin.month] - begin.day;
  for(i = (begin.month + 1); i < 13; ++i)
      days +=dpm [i];

  for(i = (begin.year + 1); i < end.year; ++i) //in between years
      days += (days_per_year + isleapyear(i));

  if(isleapyear(end.year))//end year
      for(i = 0; i < end.month; ++i){
          days += dpm[i] + 1;
      days += dpm[end.month] - end.day;
      }
  else
      for(i = 0; i < end.month; ++i)
        days += dpm[i];
      days += dpm[end.month] - end.day;

  return days;
  }


int main(int n){
  printf("Please enter the first date then the second one\n");
  begin=EnterDate();
  end=EnterDate();

  validate();
  if(n == 1)
    printf("Invalid Input!!!");
  else
      printf("Total days between these two dates is %i\n", count_days());
  return 0;
}

The code is still saying that validate is always true making the output an "Invalid Input" and I've only been able to check the program count days scarcely but when I did it was pretty far off either a year or around 200 days.

Upvotes: 1

Views: 1114

Answers (1)

Nik Bougalis
Nik Bougalis

Reputation: 10613

Let's split that ridiculously long conditional up, and add some spacing to see what's happening shall we?

if( (begin.year>end.year) ||
    ( (begin.year==end.year) && (begin.month>end.month) ) || 
    begin.year==end.year) && (begin.month==end.month) && (begin.day>end.day)))

Obviously there's at least one missing parenthesis on that third line. Even after you add it, you're missing another pair of parentheses. Let's fix those two problems, shall we?

if( (begin.year>end.year) ||
    ( (begin.year==end.year) && (begin.month>end.month) ) || 
    ( (begin.year==end.year) && (begin.month==end.month) && (begin.day>end.day)))

Still, this is pretty hard to read quickly and understand. Let's split that up and add some sane spacing, shall we?

int validate(void) 
{
    if(begin.year > end.year)
        return 1; /* time travelling is not allowed. Yet! */

    if((begin.year == end.year) && (begin.month > end.month))
        return 1; /* you can't begin after you end! */

    if((begin.year == end.year) && (begin.month == end.month) && (begin.day > end.day))
        return 1; /* finishing before you start isn't allowed by the union */

    return 0;
}

It's impossible to answer the question about the "off by 200 days" without knowing more about those arrays, like dpm and those functions you call.

Update: You posted a bit of extra code; still not quite enough, but now my spidey-sense is tingling. Something tells me that the problem is in your EnterDate which accepts dates as "1-based" (i.e. January 3, 2012 is entered as 1/3/2012) but your arrays are 0-based.

Update2: Uhm... let's see here:

int main(int n){
  printf("Please enter the first date then the second one\n");
  begin=EnterDate();
  end=EnterDate();

  validate();
  if(n == 1)
    printf("Invalid Input!!!");

I didn't go much further than that. First of all, int main(int n) isn't valid syntax for main. Second of all, I am floored that you claim to have been struggling to find the error, by claiming that your validate() function fails... how do you know? you aren't even checking it's result!!!

How about this:

int main(int argc, char **argv) {
  printf("Please enter the first date then the second one\n");
  begin = EnterDate();
  end = EnterDate();

  if(validate()) {
      printf("Invalid Input!!!\n");
      return 1;
  }

  ...

Update 4: If you had bothered to add printf statements in your count_days function to see the execution, the error(s) would have immediately become obvious to you. Try this:

int count_days(void){
    int i;
    int days=0;
    int days_per_year = 365;

    if(isleapyear(begin.year)){ // first year
        printf("%d is a leap year!\n", begin.year);

        if(begin.month == 1)
            days = dpm[begin.month] - begin.day + 1;
        else
            days = dpm[begin.month] - begin.day;
    }     
    else 
        days = dpm[begin.month] - begin.day;

    printf("At first checkpoint: %d days\n", days); 

    for(i = (begin.month + 1); i < 13; ++i)
        days +=dpm [i];

    printf("At second checkpoint: %d days\n", days); 

    for(i = (begin.year + 1); i < end.year; ++i) //in between years
        days += (days_per_year + isleapyear(i));

    printf("At third checkpoint: %d days\n", days); 

    if(isleapyear(end.year))//end year
        printf("%d is a leap year!\n", end.year);
    for(i = 0; i < end.month; ++i){
        days += dpm[i] + 1;
        days += dpm[end.month] - end.day;
    }
    else
        for(i = 0; i < end.month; ++i)
            days += dpm[i];
    days += dpm[end.month] - end.day;


    return days;
}

Upvotes: 4

Related Questions