1.需求

*题目描述

已知2010年1月1日为星期五。

设计一函数按照下述格式打印2010年以后(含)某年某月的日历,2010年以前输入的拒绝打印。

为完成此函数,设计必要的辅助函数可能也是必要的。其中输入为年分和月份。


*输入格式

年和月份


*输出格式

参照样例输出,必须符合实际日历排版


*样例输入

2010 9  


*样例输出

---------------------

Su Mo Tu We Th Fr Sa

---------------------

          1  2  3  4

 5  6  7  8  9 10 11

12 13 14 15 16 17 18

19 20 21 22 23 24 25

26 27 28 29 30


2.代码

#include <string.h>
#include <stdio.h>
#include <stdlib.h>




/*
//已知2010年1月1日为星期五
//NOTE:*******************
// 1月(31天) 2月(28或29天) 3月(31天) 4月(30天) 5月(31天) 6月(30天)
// 7月(31天) 8月(31天) 9月(30天) 10月(31天) 11(30天) 12月(31天)
样例输出
---------------------
Su Mo Tu We Th Fr Sa
---------------------
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
---------------------
*/
const static int DAYS_OF_MONTH[13] = { 0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
enum WEEK {
Mo,
Tu,
We,
Th,
Fr,
Sa,
Su,
MAX_DAY
};
static const char *WEEK_STR[MAX_DAY] = {
"Mo",
"Tu",
"We",
"Th",
"Fr",
"Sa",
"Su"
};
static inline int get_days(int year, int month) {
if (month != 2) {
return DAYS_OF_MONTH[month];
}
else if ((0 == year % 4) && ((year % 100 != 0) || (0 == year % 400))) {
return 29;
}
return 28;
}
int CalculateDay(int iYear, int iMonth) {
/* TODO: write code as below */
/* TODO: 计算该月第一天是星期几*/
int iDay = 1;
int week = Fr;
int months = (iYear - 2010) * 12 + iMonth - 1;
int month = 1;
int days = 0;
int year = 2010;
for (int i = 1;i <= months;i++) {
days = get_days(year, month);
week = (week + (days - 28)) % MAX_DAY;
if (++month > 12) {
year++;
month = 1;
}
}
iDay = week;
return iDay;
}

int main(void)
{
int iFirstDay = 1;
int iInputYear = 0;
int iInputMonth = 0;

while(iInputYear<2010)
{
printf("Please input supported year(>2010):\n");
scanf("%d", &iInputYear);
}

while (iInputMonth>12 || iInputMonth<1)
{
printf("Please input month(must between 1 and 12):\n");
scanf("%d", &iInputMonth);
}

iFirstDay = CalculateDay(iInputYear, iInputMonth);
printf("first day:%d\n", iFirstDay);
printf("first week:%s\n", WEEK_STR[iFirstDay]);
///////////////////////
/*TODO 求出本月有几天*/
///////////////////////


/////////////////////
///////////////////////
/*打印出该月的日历*/
printf("---------------------\n");
printf(" Su Mo Tu We Th Fr Sa\n");
// Su Mo Tu We Th Fr Sa

printf("---------------------\n");
///////////////////
/*TODO 打印日历*/
const char *str = " Su Mo Tu We Th Fr Sa";
const char *week_str = WEEK_STR[iFirstDay];
char *p = strstr(str, week_str);
if (!p) {
return -1;
}
for (const char *start = str;start != p;start++) {
printf(" ");
}
///////////////////
int days = get_days(iInputYear, iInputMonth);
int week = iFirstDay;
for (int i = 1;i <= days;i++) {
if (i < 10) {
printf("%d ", i);
}
else {
printf("%d ", i);
}
if (Sa == week) {
printf("\n ");
}
week = (week + 1) % MAX_DAY;
}
printf("\n");
printf("---------------------\n");
return 0;
}

3.编译

Makefile:

DBG        = -g
OPTFLAGS = -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes $(DBG) -pedantic

SRC = calendar.c
TARGET = calendar
OBJ = $(SRC:.c=.o)

default: $(TARGET)

%.o: %.c
$(CC) $(CFLAGS) -g -c -o $@ $<

$(TARGET): $(OBJ)
$(CC) -o $@ $(OBJ) $(LDFLAGS)

clean:
rm $(OBJ) $(TA

4.运行测试

日历生成程序_#include