日历生成程序

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.运行测试

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值