奇怪的输出日历在C中

时间:2016-05-13 15:45:33

标签: c date calendar codeblocks

我在C中编写了一个非常简单的日历。它以年份作为输入,然后计算该年份的日期和工作日。 假设日期0001-01-01是星期一。 除了在一个地方,我已经让它工作得很好。当它即将打印出所有第31个日期的行。 基本上出了什么问题,当它要检查是否有什么东西要打印到31日(没有)时,它会破坏工作日变量。这使得以下第31个日期错了。 是否有人可以看到我做错了什么或者想帮助我? :)

编辑忘了提及它是一个没有任何计算日期代码等公式的任务。允许使用的唯一参考是0001-01-01的日期是星期一。

继承我的代码。 (是的,它有点凌乱,但我还在学习。)

int isLeapYear(int year){
    if(((year%4==0) && (year%100!=0)) || (year%400==0)){
            return 1;
        }
    else
        return 0;
}
int getYear(){
    int year = 0;
    while(year==0 || year < 0){
        printf("Enter year: ");
        scanf("%d", &year);
        if(year > 0){
            break;
        }
        printf("Invalid input. Try again.\n\n");
    }
    return year;
}
void printWeekday(int w){
    switch(w){
        case 0:
            printf("Sun");
            break;
        case 1:
            printf("Mon");
            break;
        case 2:
            printf("Tue");
            break;
        case 3:
            printf("Wed");
            break;
        case 4:
            printf("Thu");
            break;
        case 5:
            printf("Fri");
            break;
        case 6:
            printf("Sat");
            break;
    }
}
void printMonth(int m){
    switch(m){
        case 1:
            printf("Jan");
            break;
        case 2:
            printf("       Feb");
            break;
        case 3:
            printf("       Mar");
            break;
        case 4:
            printf("       Apr");
            break;
        case 5:
            printf("       May");
            break;
        case 6:
            printf("       Jun");
            break;
        case 7:
            printf("       Jul");
            break;
        case 8:
            printf("       Aug");
            break;
        case 9:
            printf("       Sep");
            break;
        case 10:
            printf("       Oct");
            break;
        case 11:
            printf("       Nov");
            break;
        case 12:
            printf("       Dec\n");
            break;
    }
}
void calendar(int year){
    int y = 1;
    int m = 1;
    int d = 1;
    int loop = 1;
    int day = 1;
    int days_in_month[14] = {0,31,28,31,30,31,30,31,31,30,31,30,31,0};
    if(isLeapYear(year)){
        days_in_month[1] = 29;
    }
    for(m=1; m<=12; m++){
        printMonth(m);
    }
    while(loop){
        int weekday = 1;
            for(y=1; y<=year; y++){
                for(m=1; m<=12; m++){
                    for(d=1; d<=31; d++){

                        if(weekday%7 == 0){
                           // printf("h");
                            weekday = 0;
                        }
                        if(y==year){
                            if(day>days_in_month[m]){
                                printf("          ");
                                printf("%d", weekday);
                                break;
                            }else if(d == day){
                                //printf("%d", weekday);
                                if(m == 1){
                                    printf("%02d ", d);
                                    printWeekday(weekday);
                                }else if(m == 12){
                                    printf("    %02d ", d);
                                    printWeekday(weekday);
                                    printf("\n");
                                }else{
                                    printf("    %02d ", d);
                                    printWeekday(weekday);
                                }
                            }
                        }
                        if(d<=days_in_month[m]){
                            weekday = weekday + 1;
                        }
                    }
                }
            }
            day++;
            if(day == 32){
                break;
            }
        }
}
int main()
{
    int end = 1;
    while(end){
        int year = getYear();
        printf("                                                         %d\n", year);
        calendar(year);
        printf("\nEnter 0 to quit: ");
        scanf("%d", &end);
        //system("cls");
    }
    return 0;
}

2 个答案:

答案 0 :(得分:0)

不是持有工作日变量,而是可以调用一个函数来计算给定日期的星期几。为此,您可以使用Tomohiko Sakamoto的星期几算法。

int dayofweek(int d, int m , int y){
    static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
    y -= m < 3;
    return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
// 0 - Sunday 
// 1 - Monday and so on

如果您想了解此算法,可以在此处查看详细说明:https://www.quora.com/How-does-Tomohiko-Sakamotos-Algorithm-work

但是既然你是初学者,我就不会重新考虑它:)它有点令人困惑。

执行此操作后,您可以将日历功能简化为

void calendar(int year) {

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

    if (isLeapYear(year)) {
        days_in_month[2] = 29;
    }
    for (int m = 1; m<=12; m++) {
        printMonth(m);
    }

    for (int d = 1; d<=31; d++) {
        for (int m = 1; m<=12; m++) {
            if (d <= days_in_month[m]) {
                int weekday = dayofweek(d, m, year);
                printf("%02d ", d);
                printWeekday(weekday);
                printf("    ");
            }
            else {
                printf("          ");
            }
        }
        printf("\n");
    }               

}

这实际上是一种更有效的方式来产生工作日而不是整年的循环

答案 1 :(得分:0)

这里,在calendar()函数内部添加以下代码:

if(day>days_in_month[m] /*Add this code: */ && d>days_in_month[m]){
      printf("          ");
      printf("%d", weekday);
      break;
}else if(d == day){...

哪里有问题?那么,你看到了游行的第31天了吗?星期六: enter image description here

在迭代结束时(我的意思是for(d=1; d<=31; d++){循环)你迭代工作日。所以4月初应该​​是星期天。如果您检查结果,这是有效的。

但是,你按星期几计算工作日。因此,当我们在3月3日打印31时,我们的day变量等于31.

现在,3月结束了(我们打印3月31日),我们周日的工作日开始了。我们去计算四月的日子。但是看看你的代码,在for(d=1; d<=31; d++)循环内,你有if(day>days_in_month[m]) {break;}。 当我们的程序检查4月的第一天,并且day等于31时,它将使用break指令停止计算4月的天数。我们去计算五月的日子。但我们的工作日仍然是周日。如果您看到有效代码,则可能应该是星期二。但是当day变量等于31时,首先可以从星期日开始。从5月1日开始,所有日子计算错误。

与LEAPS年有关的问题: 因为你使用这个:

if(isLeapYear(year)){
    days_in_month[2] = 29;
} 

每年增加第29天(所以你在前三年增加了第29天,你会看到第4年1月1日结果:))。

要解决此问题,请删除这些代码。在循环内部持续数月,添加代表天数的变量:

for(m=1; m<=12; m++){                   
 int monthDays = days_in_month[m]; /*Add this variable*/
 if (m==2 && isLeapYear(y)) 
   monthDays++; // Add 29th day to feb. of leap year     
 for(d=1; d<=31; d++){...

在功能内部,将所有days_in_month[m]替换为monthDays