精華區beta C_and_CPP 關於我們 聯絡資訊
/* * 我採用偷吃步的方法,找了3個定位點,再 * 根據輸入年與定位點的差,再算出calendar的縮排(indent) * 我採用的曆法規則為:1752年前4年一潤, * 1752年後4年一潤,100年不潤,400年一潤。 */ #include<stdio.h> void display(int,int); main() { int year, month; printf("輸入年(1到9999),月(1到12):\n"); scanf("%d%d",&year,&month); while(year>9999 || year<1 || month>12 || month<1){ printf("Out of range! Input again.\n" " 輸入年(1到9999),月(1到12):\n"); scanf("%d%d",&year,&month); } display(year,month); return 0; } void display(int yy, int mm) { int indent(int, int, int*); int dd[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int i,cols=0; printf("\nYear:%d Month:%d\n",yy,mm); printf("^^Sun^^Mon^^Tue^^Wed^^Thu^^Fri^^Sat^^\n"); for(i=1 ; i<=indent(yy, mm, dd) ; ++i){ printf(" "); ++cols; } if(yy!=1752 || mm!=9) for(i=1 ; i<=dd[mm-1] ; ++i){ printf("%5d",i); ++cols; if(cols%7==0) putchar('\n'); } else{//西元1752年9月 printf("%5d%5d",1,2); cols+=2; for(i=14 ; i<=30 ; ++i){ printf("%5d",i); ++cols; if(cols%7==0) putchar('\n'); } } putchar('\n'); } int indent(int year, int month, int*d) { void after_Jan(int*, int, int*); int idt; if(year>=1753){ idt=(year-1753)*497/400+1; /* * 上面一行是由下式化簡而來, * diff=year-1753; * idt=diff+diff/4-diff/100+diff/400+1; * 我採用1753年1月1日星期1為基準點,故加1 */ if(month>=2){ if((year%4==0 && year%100!=0) || year%400==0) d[1]=29; after_Jan(&idt, month, d); } } else if(year<=1751){ idt=year-1+(year-1)/4+6; //上式是採用西元1年1月1日星期六為基準,故加6 if(month>=2){ if(year%4==0) d[1]=29; after_Jan(&idt, month, d); } } else{//year==1752 idt=3;//西元1752年1月1日為星期3 if(month>=2){ d[1]=29; d[8]=19;//西元1752年的9月只有19天 after_Jan(&idt, month, d); } } return idt%7; } void after_Jan(int*space, int m, int*d) { int*p=d; while(p-d<=m-2) *space+=*p++; /*用指標寫可讀性差了一點,上面的敘述用陣列改寫: * for(int i=0 ; i<=m-2 ; ++i) * *space+=d[i]; */ } /* cakewalks * miracle@ms3.url.com.tw * 1999.10.29 */ -- ※ 發信站: 批踢踢實業坊(ptt.twbbs.org) ◆ From: 140.116.28.163