Simple case 2 of C language original experimental project (perpetual calendar program)

//This program is a perpetual calendar implemented using the year calculation method;

//The code contains a lot of comments for readers to read;

//Use the C standard library (portable program);

//Can run under Linux/Mac os/Windows;

// Plagiarism and reprinting without permission is strictly prohibited;

//If it is helpful to you, please like, favorite or forward;

//The source code is here, I hope to inspire you;

//C language perpetual calendar applet.c

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

/*函数功能:判断是否是闰年*/
bool is_leap_year(int year);
/*-------------------------------------*/

/*函数功能:打印n个空格数*/
void print_space(int n);
/*-------------------------------------*/

/*函数功能:计算当前年份第一天是星期几*/
int day_of_week(int year);
/*-------------------------------------*/

/*函数功能:将数字转化成对应的汉字月份*/
char *print_month(int month);
/*-------------------------------------*/

/*函数功能:输出日历中每月份的表头*/
void print_head_of_month(int month);
/*-------------------------------------*/

/*函数功能:打印当前年份的日历*/
void print_calendar(int year);
/*-------------------------------------*/

/*函数功能:判断用户输入是否正确*/
int get_correct_choice(void);
/*-------------------------------------*/

/*函数功能:获取用户输入*/
int get_first(void);
/*-------------------------------------*/

int main(void)
{
    
    
    int ch, year;

    do
    {
    
    
        printf("=====================================\n");
        puts("         欢迎进入万年历查询系统!");
        printf("=====================================\n");
        printf("请输入您要查询的年份:");
        scanf("%d", &year);
        printf("\n\n\n\n\n\n\n\n\n\n\n");
        print_calendar(year);
        printf("您希望继续查询吗?(y/n)\n");
        printf("请您输入选择:");
        ch = get_correct_choice();
    } while (ch != 'n');
    puts("欢迎下次使用!");

    return 0;
}

bool is_leap_year(int year)
{
    
    
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? true : false;
    //4年为一闰年,100年不是闰年,而400年又是一闰年;
}

void print_space(int n)
{
    
    
    while (n--)
    {
    
    
        printf(" ");
    }
    return;
}

int day_of_week(int year)
{
    
    
    return ((year + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400) % 7);
    //公元元年的第一天是星期一,后面每一年与公元元年的差值再对7取余数即可得到当前年份的第一天是星期几;
}

char *print_month(int month)
{
    
    
    char *month_names[] = {
    
    
        "一月", "二月", "三月", "四月",
        "五月", "六月", "七月", "八月",
        "九月", "十月", "十一月", "十二月"};
    return (month > 0 && month < 13) ? month_names[month - 1] : " ";
}

void print_head_of_month(int month)
{
    
    
    print_space(12);
    printf("%s", print_month(month));            //打印的是奇数月份的名称;
    print_space(28);                             //空格隔开两月月历的表头部分;
    printf("%s     \n", print_month(month + 1)); //打印的是偶数月份的名称;
    printf("_____________________________");
    print_space(5); //空格隔开两月月历的表头部分;
    printf("_____________________________\n");
    printf("  日  一  二  三  四  五  六");
    print_space(6); //空格隔开两月月历的表头部分;
    printf("  日  一  二  三  四  五  六\n");
    return;
}

void print_calendar(int year)
{
    
    
    bool odd, even;
    int i, j, k, m, n, days;
    int a[13] = {
    
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    print_space(26);
    printf("%d年日历表\n\n", year);
    days = day_of_week(year); //计算当前年份第一天是星期几;
    if (is_leap_year(year))
    {
    
    
        ++a[2]; //闰年则2月份增加一天;
    }
    for (i = 1; i < 13; i += 2)
    {
    
    
        m = n = 0;              //累计奇偶月份的天数;
        odd = even = false;     //判断奇偶月份的月历是否打印完成;
        print_head_of_month(i); //输出月历的表头;
        for (j = 0; j < 6; j++) //每月月历最多是6行;
        {
    
    
            if (0 == j) //定位每月第一行的每月1日的输出位置;
            {
    
    
                print_space(days * 4);
                for (k = 0; k < 7 - days; k++) //打印第i月的第一行日期;
                {
    
    
                    printf("%4d", ++m);
                }
                print_space(6); //奇偶月份日期用空格分隔;
                days = (days + a[i] % 7) % 7;
                //判断右半部分偶数月份的第i + 1月 1 日是星期几,a[i]是上个月(奇数月份第i月)的总天数;
                print_space(days * 4);
                for (k = 0; k < 7 - days; k++) //打印第i + 1月的第一行日期;
                {
    
    
                    printf("%4d", ++n);
                }
                putchar('\n');
            }
            else
            {
    
    
                for (k = 0; k < 7; k++) //左半部分打印奇数月份的第i月的日期(2-6行);
                {
    
    
                    if (m < a[i])
                    {
    
    
                        printf("%4d", ++m);
                    }
                    else
                    {
    
    
                        print_space(4);
                    }
                    if (m == a[i])
                    {
    
    
                        odd = true; //标记奇数月份打印完成;
                    }
                }
                print_space(6);
                for (k = 0; k < 7; k++) //右半部分打印偶数月份的第i + 1月的日期(2-6行);
                {
    
    
                    if (n < a[i + 1])
                    {
    
    
                        printf("%4d", ++n);
                    }
                    else
                    {
    
    
                        print_space(4);
                    }
                    if (n == a[i + 1])
                    {
    
    
                        even = true; //标记偶数月份打印完成;
                    }
                }
                putchar('\n');
                if (odd && even)
                {
    
    
                    break; //所有月份都打印完成则退出循环;
                }
            }
        }
        putchar('\n');
        days = (days + a[i + 1] % 7) % 7;
        //判断下月1日是星期几,a[i + 1]是上个月(偶数月份第i + 1月)的总天数;
    }
    return;
}

int get_correct_choice(void)
{
    
    
    int ch;

    ch = get_first();
    while (ch != 'y' && ch != 'n')
    {
    
    
        printf("输入无效!请输入y或者n:");
        ch = get_first();
    }
    return ch;
}

int get_first(void)
{
    
    
    int ch;

    do
    {
    
    
        ch = getchar();
    } while (isspace(ch));
    while (getchar() != '\n')
        continue;
    return ch;
}

//-------------

//----------------------------August 2, 2020-------------- -----------------

Guess you like

Origin blog.csdn.net/m0_46181359/article/details/107748071