c语言课程设计 万年历

 该程序仅在dev运行过,可能存在一些变量的赋值问题,读者有需要可以自己阅读理解,自行修改

这个程序也是我第一次设计的课程设计,可能思想方面还不太成熟,有些代码运行效率不高。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>        //头文件time,用于获取当前时间; 

int year,month,day;        //全局变量;

/*定义一个平年数组和闰年数组,方便后面做选择*/ 
int monthdays[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},    
                      {0,31,29,31,30,31,30,31,31,30,31,30,31}};
char months[13][15]={"","January","February","March","April","May","June","July",
                        "August","September","October","November","December"};
int weekofmonth[13];    //用于储存每个月1号的星期值; 

/*用于输出星期值的中文字体*/
char weekend[7][20]={"日","一","二","三","四","五","六"};

/*关于time.h头文件的所声明的结构体变量struct tm *localtp,
struct tm

    struct tm_sec;        //秒取值区间为[0,59]; 
    struct tm_min;          //分取值区间为[0,59]; 
    struct tm_hour;          //时取值区间为[0,23]; 
    struct tm_mday;          //一个月中日期取值区间为[1,31]; 
    struct tm_mon;          //月份(从一月开始,0代表一月)取值区间为[0,11]; 
    struct tm_wday;          //星期取值区间为[0,6],其中0代表星期天,1代表星期一; 
    struct tm_yday;          //从每年1月1号开始的天数,其中0代表1月1日 
    struct tm_isdst;      //夏令时标识符,夏令时tm_isdst为正,否则tm_isdst为0; 
}*/ 
struct tm *localtp;

int IsLeap(int y);        //此函数在本程序频繁使用,主要是判断平、闰年;    
void Menu();            //菜单栏界面; 
void Isrun();            //功能1:判断是否为闰年函数; 
void All_year();        //功能3:打印全年月历表; 
void The_day_of_the_week();
void One_month();
void timenows();
void error();
int Countday(int year,int month,int day);

                  

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[])
{
    int num;
    system("color 0a"); 
    while(1)
    {     Menu();
        scanf("%d",&num);
        system("cls");
        /*通过switch达到选择不同功能的效果*/
        switch(num)
        {
            case 0: exit(0);
            case 1: Isrun();break;
            case 2: The_day_of_the_week();break;
            case 3: All_year();break;
            case 4: One_month();break;
            case 5: timenows();break;
            default :error(); break;
        }
    }
    
    system("pause");
    

    return 0;
}
/*主菜单界面*/ 
void Menu()    
{
    printf("-------------------------------------\n");
    printf("|         1) 查询闰年              |\n");
    printf("|         2)  查询星期              |\n");
    printf("|         3)  全年月历              |\n");
    printf("|         4)  本月月历              |\n");
    printf("|         5)  查看距今多少天        |\n");
    printf("|         0)  退出程序              |\n");
    printf("-------------------------------------\n");
    
    
}

/*功能1:输入年份,判断平、闰年*/
void Isrun()
{
    printf("判断闰年:\n");
    printf("请输入您要查询的年份:\n");
    scanf("%d",&year);
    
    if(IsLeap(year))    printf("该年为闰年!\n");
    else             printf("该年为平年!\n");
    system("pause");
    system("cls");
}

/*功能2:输出日期,查询星期值*/


void The_day_of_the_week()
{
    printf("判断星期几:\n");
    printf("请输入您要查询的日期:\n");
    
    int i,leap,t,days=0;
    scanf("%d %d %d",&year,&month,&day);
    
    for(i=1900;i<=year-1;i++)        //把每年对7求余后的天数储存起来,主要是为了后面日期排列做准备; 
    {
        if(IsLeap(i))         days+=366%7;
        else                   days+=365%7;
    }
    
    if(IsLeap(year))        leap=1;
    else                  leap=0;
    for(i=1;i<=month;i++)            //把目标年的每一个月1号进行对7求余后的天数储存起来;days的主要作用也在此;
    {
        weekofmonth[i]=(days+1)%7;   //weekofmonth[i]就是存储每个月1号的星期值 
        days+=monthdays[leap][i];        
    }
    
    t=(weekofmonth[month]+day-1)%7;        //这里同样是求余原理,因为前面求的是1号,所以要day-1; 
    
    printf("%d年%d月%d日是星期%s\n",year,month,day,weekend[t]);
    system("pause");
    system("cls");
}


/*功能3:打印全年月历表*/
void All_year()
{
    printf("\t打印月历表:\n");
    printf("请输入您要打印的年份:\n");
    scanf("%d",&year);
    
    int days=0,i,leap=0,j,k=0,m=0;

    for(i=1900;i<=year-1;i++)        //这里跟功能2原理一样 
    {
        if(IsLeap(i))         days+=366%7;
        else                   days+=365%7;
    }
    
    if(IsLeap(i))        leap=1;
    else                  leap=0;
    for(i=1;i<=12;i++)
    {
        weekofmonth[i]=(days+1)%7; 
        days+=monthdays[leap][i];
    }
    
    for(i=1;i<=12;i++)                //打印全年月历表 
    {
        printf("-------%s(%d)-------\n",months[i],year);
        printf("\n");
        printf("Sun Mon Tue Wed Thu Fri Sat\n");
        //printf("===========================\n");
        for(j=1;j<=weekofmonth[i];j++)
        {
            printf("    ");                    //对应的星期值前面用空格承接; 
        }
        k=weekofmonth[i];                    //用k进行计数,逢7换行;
        for(m=1;m<=monthdays[leap][i];m++)
        {
            printf("%3d ",m);
            k++;                    
            if(k%7==0)   printf("\n");
        }
        
        printf("\n");
        printf("===========================\n");
        printf("\n");
        printf("\n");
    }
    system("pause");
    system("cls");
}

/*功能4:打印本月日历表
    这里跟功能3大致一样,我不再过多介绍*/ 
void One_month()
{
    printf("\t打印本月日历表:\n");
    printf("请输入您要打印的年月份:\n");
    scanf("%d %d",&year,&month);
    
    int days=0,i,leap=0,j,k=0,m=0;
    
    for(i=1900;i<=year-1;i++)
    {
        if(IsLeap(i))         days+=366%7;
        else                   days+=365%7;
    }
    
    if(IsLeap(i))        leap=1;
    else                  leap=0;
    for(i=1;i<=month;i++)
    {
        weekofmonth[i]=(days+1)%7; 
        days+=monthdays[leap][i];
    }
    
    
    printf("-------%s(%d)-------\n",months[month],year);
    printf("\n");
    printf("Sun Mon Tue Wed Thu Fri Sat\n");
    for(j=1;j<=weekofmonth[month];j++)
    {
        printf("    ");
    }
    k=weekofmonth[month];
    for(m=1;m<=monthdays[leap][month];m++)
    {
        printf("%3d ",m);
        k++;
        if(k%7==0)   printf("\n");
    }
    printf("\n");
    printf("===========================\n");
    printf("\n");
    printf("\n");
    
    system("pause");
    system("cls");
}

int IsLeap (int y)
{
    return (y%400==0||y%4==0&&y%100!=0);

/*功能5:查询距今天数
    这里我用的方法比较土,采用统计天数法,通过分别计算两个日期的天数,
    然后相减达到相距天数, 同时也是最为方便简单的一种算法*/ 

void timenows()
 {    
    printf("请输入您要查询的日期:\n");
    
    int i,leap=0,t=0,days=0,nums=0,num=0,n=0;
    time_t now,t1;            
    t1=time(&now);            //这里通过头文件time.h获取当前时间值; 
    scanf("%d %d %d",&year,&month,&day);
    
    num=Countday(year,month,day);        //统计目标年份天数; 

    localtp = localtime(&now);        //通过localtime转换为本地时间; 
    printf("现在日期和时间是:          %d年%d月%d日%d:%d:%d\n",localtp->tm_year+1900,
            localtp->tm_mon+1,localtp->tm_mday,localtp->tm_hour,localtp->tm_min,
            localtp->tm_sec);
    
    /*这里的函数跟上面的是一样的,但是实参不同,
    因为计算方式一样,所以采用同一个函数,提高代码利用率*/        
    nums=Countday(localtp->tm_year+1900,localtp->tm_mon+1,localtp->tm_mday);
    
    if(num>nums)
    {
        n=num-nums;
        printf("距离今天还有%d天\n",n);
    }    
    else
    {
        n=nums-num;
        printf("距离今天已过去%d天\n",n);
    }                
     
    for(i=1900;i<=year-1;i++)
    {
        if(IsLeap(i))         days+=366%7;
        else                   days+=365%7;
    }
    
    if(IsLeap(i))        leap=1;
    else                  leap=0;
    for(i=1;i<=month;i++)
    {
        weekofmonth[i]=(days+1)%7; 
        days+=monthdays[leap][i];
    }
    
    t=(weekofmonth[month]+day-1)%7;
    
    printf("%d年%d月%d日是星期%s\n",year,month,day,weekend[t]);
    
    /*星期六、日为法定节假日*/ 
    if(t==0||t==6)    
        printf("%d年%d月%d日为法定节假日\n",year,month,day);
    else
        printf("%d年%d月%d日不是法定节假日\n",year,month,day);
    
    system("pause");
    system("cls");
}

/*统计天数的函数*/ 
int Countday(int year,int month,int day)
{
    int i,days=0,leap=0;
    for(i=1900;i<year-1;i++)
    {
        if(IsLeap(i))            days+=366;
        else                     days+=365;
    }
 
        if(IsLeap(i))        leap=1;
        else                  leap=0;
    for(i=1;i<=month-1;i++)
    {
        days+=monthdays[leap][i];
    }
    days+=day; 
    return days;
}

/*对输入指令错误进行提示*/
void error()            
{
    printf("输入错误!!!请重新输入\n");
    
    system("pause");
    system("cls"); 
}

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值