sdnyzjzx 发表于 2010-12-5 20:23:12

万年历

本帖最后由 sdnyzjzx 于 2010-12-17 11:43 编辑

C语言学习视频到了第十一个了,收获越来越多,再次感谢Nisy老师,完成了万年历代码编写要求,很高兴,分享一下快乐!并恳请批评指正,谢谢!
代码在Tc2中编译,后来在记事本里加了部分中文注释,带有中文注释语句应该编译不过。



/* yi 2010-12-13 (xing qi 1) wei ji zhun */
int year,m,d,w;/* year month date week */
int sum=0;    /* di ji tian */
int tt=0;   /* ju li ji zhun zhong tian shu */
int a = {0,31,28,31,30,31,30,31,31,30,31,30,31}; /* mei ge yue tian shu */
int b = {0,7,1,2 ,3,4,5,6};
int k;       /* biao ji shi fou run nian */

void sfrn(year)/* 判断是否闰年 */
{
      if((year%4==0 && year%100 !=0) || year%400 == 0)
      {
      k=1;
      }
      else
      {
      k=0;
      }
}

void djt (year,m,d)/* 输入日期是本年第几天 */
{
      int i=0;
      sfrn(year);
      for(i=0;i<m;i++)
      {
      sum = sum + *(a+i);
      }
        sum=sum+d;
        if(m>2)
        {
      sum = sum + k;
        }
}

void week(year,m,d)/* 判断星期几 */
{
      int i=0;
      int j=0;
      if(year<=2010)
      {
      djt(year,m,d);
                if(year==2010)
                {
                        if(sum<=347)
                        {
                        tt=347-sum;
                        }
                        else
                        {
                        tt=sum-347;
                        }
                }
                else
                {       tt=tt-sum;
                        for(i=year;i<=2010;i++)
                        {
                        sfrn(i);
                        tt=tt+365+k;
                        }
                        tt=tt-18;
                }
                j=tt%7;
                        if(j==0)
                        {
                        w=1;
                        }
                        else
                        {
                              if(year <2010 || (year==2010 && sum<=347))
                              {
                              w=8-j;
                              }
                              else
                              {
                              w=1+j;
                              }
                        }
      }
      else
      {
      djt(year,m,d);
                for(i=2010;i<year;i++)
                {
                sfrn(i);
                tt=tt+365+k;
                }
                tt=tt-347+sum;
                j=tt%7;
                w=1+j;
      }
}

void show(year,m,d) /* 显示 */
{
      int n=0;
      int i=0;
      int j=0;    /* 当前月数有几天*/
      int x,y;
      int x0,y0;/* 记录当前输入月数与天数位置 */
      int w1=31;
      int d1=0;/* 星期几 */
      x0=y0=1;
      week(year,m,d);
      w1=d;
      while(w1>7)
      {
      w1=d-7*n;
      n++;
      }
      d1=w-w1+1;
      if(d1<=0)
      {
      d1=d1+7;
      }
      clrscr();
      if(m==2)
      {
      sfrn(year);
      j = *(a+2)+k;
      }
      else
      {
      j = *(a+m);
      }
      x=10;
      y=5;
      gotoxy(15,2);
      printf("== %d nian %d yue ==",year,m);
      for (i=1;i<8;i++)
      {
      gotoxy(x,y);
      printf("%d",*(b+i));
      x=x+5;
      }
      if(d1==7)
      {
      x=10;
      }
      else if(d1==1)
      {
      x=15;
      }
      else if(d1==2)
      {
      x=20;
      }
      else if(d1==3)
      {
      x=25;
      }
      else if(d1==4)
      {
      x=30;
      }
      else if(d1==5)
      {
      x=35;
      }
      else if(d1==6)
      {
      x=40;
      }
      y=7;
      for (i=1;i<=j;i++)
      {
      gotoxy(x,y);
                if(i==d) /* 记录当前输入月数与天数位置 */
                {
                x0=x;
                y0=y;
                }
      printf("%d",i);
      x=x+5;
                if(x>40)
                {
                printf("\n");
                x=10;
                y=y+2;
                }
      }
      gotoxy(1,15);
      printf("\n\nNin de shu ru %d-%d-%d shi ",year,m,d);
      printf(" No.%d day",sum);
      printf("xing qi ( %d )\n",w);
      printf("\nEsc to exit.");
      printf("   row chang time .");
      gotoxy(x0,y0);
}

int rqhfx(year,m,d)/* 日期合法性检测 */
{
      sfrn(year);
      if(year<0||m<0||m>12||d<0||d>31)
      {
      return 0;
      }
      else if((m==2 && d>(28+k)) || (m==4 && d>30)||
      (m==6 && d>30) ||(m==9 && d>30)||(m==11 && d>30))
      {
      return 0;
      }
      else
      {
      return 1;
      }
}

int shuru(c)   /* 显示后,判断输入什么键。 */
{
      if(c==0x48)                  /*up 年 + 1 */
      {
      year++;
      sum=0;
      tt=0;
      return 0;
      }
      else if(c==0x50 && year>1)   /*down 年 - 1 */
      {
      year--;
      sum=0;
      tt=0;
      return 0;
      }
      else if(c==0x4b && m>1)      /*left 月 - 1 */
      {
      m--;
      sum=0;
      tt=0;
      return 0;
      }
      else if(c==0x4b && m==1)   /* 处理到了 1月再减 1 的问题 */
      {
      sum=0;
      m=12;
      year--;
      return 0;
      }
      else if(c==0x4d && m<12)   /*right 月 + 1 */
      {
      m++;
      sum=0;
      tt=0;
      return 0;
      }
      else if(c==0x4d && m==12)/*处理到了12月再加1的问题 */
      {
      sum=0;
      m=1;
      year++;
      return 0;
      }
      else if(c==0x1b)             /*Esc*/
      {
      return 1;
      }
      else         /* 有点小问题没解决好,任意键都会显示,跟 getch()取到的光标键有关系 ; 问题得到了解决,详细情况见2楼,这里修改一下: 改为 else if( c != 0) */
      {
      return 2;
      }
}
main()
{
      char c=0;
      intq=0;
      inti=0;
start:
      clrscr();
      printf("Please input year month day :");
      scanf("%d %d %d",&year,&m,&d);
      q=rqhfx(year,m,d);
      if(q==0)
      {
      printf("\n\nYour input is error !!! Try again .\n");
      getch();
      goto start;
      }
work:
      show(year,m,d);
work2:
      c=getch();
      i=shuru(c);
      if (i==0)
      {
      goto work;
      }
      else if(i==1)
      {
      goto end;
      }
      else if(i==2)
      {
      gotoxy(3,20);
    /*    printf("%c %c",0x1,0x7); */
      printf("\n Iput error ! Try again ...");
      goto work2;
      }
end:
      clrscr();
      gotoxy(10,2);
      printf("\n\n======Thank you ! Good bye !======");
      getch();
      clrscr();
}

Nisy 发表于 2010-12-6 10:10:03

总体上不错
模块化设计的也不错
show函数有待改进

PS: 尽量不要在程序中出现goto指令

sdnyzjzx 发表于 2010-12-8 09:17:43

今天想到一个每次都会打印输入出错提示的办法,如果键盘输入的不是四个方向键或Esc键的话,就返回值2,提示键盘输入错误,问题是当键盘输入四个方向键时,会先得到一个 0 ,再得到 0x48 0x 50 0x 4B 0x 4D,主要就是要解决第一个得到的0的问题,我这样来修改
      else   --------> 改为 else if( c != 0)
      {
      return 2;
      }
这样就可以解决每次因为输入方向键得到 0 与 0x48 0x 50 0x 4B 0x 4D 的问题了。

不过经测试,现在程序还没解决一个问题:在检测日期合法性时,没有过滤掉非数字键,要继续完善一下。
页: [1]
查看完整版本: 万年历