Error generating C calendar

Asked

Viewed 574 times

2

was working on a program that generates a calendar for a month however it is not working properly with long years as in March 1004 the first day begins Wednesday and the last on Friday.

March 1004

Sun  Mon  Tue  Wed  Thu  Fri  Sat
            1    2    3    4    5
  6    7    8    9   10   11   12
 13   14   15   16   17   18   19
 20   21   22   23   24   25   26
 27   28   29   30   31

the month of February 1004 is generating the calendar correctly

February 1004

Sun  Mon  Tue  Wed  Thu  Fri  Sat
            1    2    3    4    5
  6    7    8    9   10   11   12
 13   14   15   16   17   18   19
 20   21   22   23   24   25   26
 27   28   29 

but for the year 2004 it does not generate the calendar correctly, because the first day of February 2004 is Sunday and the last also is Sunday..

February 2004

Sun  Mon  Tue  Wed  Thu  Fri  Sat
                                1
  2    3    4    5    6    7    8
  9   10   11   12   13   14   15
 16   17   18   19   20   21   22
 23   24   25   26   27   28   29

and the month of March 1987 the first day falls on Sunday and the last on Tuesday. How to solve this mistake?

Sun  Mon  Tue  Wed  Thu  Fri  Sat
                                1
  2    3    4    5    6    7    8
  9   10   11   12   13   14   15
 16   17   18   19   20   21   22
 23   24   25   26   27   28   29
 30   31 

Follows the code:

#include <ctime>
#include <cstdio>

const char *months[]={
                      "\nJanuary","\nFebruary","\nMarch","\nApril","\nMay","\nJune","\nJuly","\nAugust","\nSeptember","\nOctober","\nNovember","\nDecember"
                     };

int month_days[] = {31, 28, 31, 30, 31, 30, 31 ,31 ,30, 31, 30, 31};

int first_day_year(int year)
{
    int first_day;
    int x;
    int y;
    int z;

    x = (year - 1.)/4.0;
    y = (year - 1.)/100.;
    z = (year - 1.)/400.;

    first_day = (year + x - y + z) %7;

    return first_day;
}

int leapyear(int year)
{
    if(__isleap(year))
      month_days[2] = 29;
      return 1;
    else 
      month_days[1] = 28;
      return 0;
}

int calendar(int month, int year, int first_day)
{
    int i;

    printf("%s %d\n\n", months[month], year);
    printf("Sun  Mon  Tue  Wed  Thu  Fri  Sat\n");

    for(i = 0; i < month; i++)
    {
        first_day = ((first_day + month_days[month])%7);
    }

    for(i = 1; i <= 1 + first_day * 5; i++)
    {
        printf(" ");
    }

    for(i = 1; i <= month_days[month]; i++)
    {
        printf("%2d", i);

        if((i + first_day)%7 > 0)
            printf("   ");
        else
            printf("\n ");
    }
}

int main(void)
{
    int year;
    int month;
    int first_day;

    do{
        printf("Enter a month (1 - 12): ");
        scanf("%d", &month);
    } while (month < 1 || month > 12);

    do{
        printf("Enter a year (1000 - 3000): ");
        scanf("%d", &year);
    } while (year < 1000 || year > 3000);

    first_day = first_day_year(year);

    leapyear(year);

    calendar(month, year, first_day);

    printf("\n");

    return 0; 
}
  • is linguagen C it turns out he was invalidating tags so I put c++

  • I already fixed the tag.

1 answer

2


There are some bugs that need to be fixed:

  • The array of months with missing value

    The array month_days you are using:

    int month_days[] = {31, 28, 31, 30, 31, 30, 31 ,31 ,30, 31, 30, 31};
    

    You do not play with what you are using for positions and should therefore become:

    int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31 ,31 ,30, 31, 30, 31};
    

    In which the first position was added as 0 so that the month of position 1 gives the days of January.

  • The function leapyear has incorrect months and lack of { } to the if and else for these have two instructions each

    You can fix it like this:

    int leapyear(int year)
    {
         if((year% 4 == 0 && year%100 != 0) || year%400 == 0){
              month_days[2] = 29; //agora [2] está certo devido ao primeiro ponto
              return 1;
         }
    
         //else é desnecessário basta fazer o retorno diretamente
         return 0;
    }
    
  • Construction from the first day to the wrong month

    In function calendar, the definition of first_day is not being done correctly because you are not using the variable i of the cycle, as well as the beginning should be another recital of the amendments I proposed above.

    Would then stay so:

    int calendar(int month, int year, int first_day)
    {
        int i;
    
        printf("%s %d\n\n", months[month-1], year); //month-1 para imprimir o correto
        printf("Sun  Mon  Tue  Wed  Thu  Fri  Sat\n");
    
        for(i = 1; i < month; i++) //agora começa em 1
        {
            //+month_days[i] e não +month_days[month] que era o problema maior 
            first_day = ((first_day + month_days[i])%7); 
        }
        ...
    

    See this version working on Ideone

Edit:

To keep the month days array without the value 0 initial it is necessary to adjust the function calendar and the leap_year:

int month_days[] = {31, 28, 31, 30, 31, 30, 31 ,31 ,30, 31, 30, 31}; //sem o 0
...

int leapyear(int year)
{
    if((year% 4 == 0 && year%100 != 0) || year%400 == 0){
      month_days[1] = 29; //agora com mês posição 1, que é o segundo
      return 1;
    }

    return 0;
}
...
int calendar(int month, int year, int first_day)
{
    int i;
    month--;//agora reduz o próprio month, pois em todos os locais que é
    //utilizado daqui para a frente tem de ter 1 a menos

    printf("%s %d\n\n", months[month], year); //sem -1 aqui, pois já foi reduzido acima
    printf("Sun  Mon  Tue  Wed  Thu  Fri  Sat\n");

    //volta ao i=0 que era o que tinha. month também tem agora -1 que veio de cima
    for(i = 0; i < month; i++) 
    {
        first_day = ((first_day + month_days[i])%7); 
    }

See the version without 0 operating on Ideone

Browser other questions tagged

You are not signed in. Login or sign up in order to post.