使用C语言打印月历需要进行如下步骤:
第一步:确定需求
我们需要编写一个程序,根据用户输入的年份和月份,输出该月份的日历。用户输入的年份和月份需要通过命令行参数传递。
第二步:分析问题
要输出一个月份的日历,我们需要知道这个月有多少天,以及从哪一天开始。根据该月第一天是星期几,我们可以推算出每天在日历中的位置。因此,我们需要解决以下问题:
- 根据年份和月份计算该月的天数
- 计算该月第一天是星期几
- 打印日历
第三步:解决问题
根据年份和月份计算该月的天数
我们可以使用一个数组记录每个月份的天数,然后根据用户输入的年份和月份,查找对应的天数。需要注意的是,闰年的2月份有29天。
int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int is_leap_year(int year) {
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
int get_days(int year, int month) {
if (month == 2 && is_leap_year(year)) {
return 29;
} else {
return days[month - 1];
}
}
计算该月第一天是星期几
我们可以使用Zeller's congruence公式来计算某一天是星期几。具体来说,公式如下:
h = (q + ((m + 1) * 26) / 10 + k + k / 4 + j / 4 + 5j) % 7
其中,
- h是星期几,0表示星期日,1表示星期一,以此类推。
- q是月份中的某一天。
- m是月份,3表示3月,4表示4月,以此类推,1和2表示上一年的13月和14月。
- k是年份的后两位数。
- j是年份的前两位数。
int get_day_of_week(int year, int month) {
int q = 1;
int m = (month == 1 || month == 2) ? month + 12 : month;
int k = year % 100;
int j = year / 100;
return (q + ((m + 1) * 26) / 10 + k + k / 4 + j / 4 + 5 * j) % 7;
}
打印日历
为了使输出的结果美观,我们可以使用表格来展示日历。可以使用printf函数打印表格的各个元素,其中需要使用%2d来保持数字的对齐。需要注意的是,输出的第一行需要打印该月份的名称,可以使用一个数组来保存月份的名称。
void print_calendar(int year, int month) {
printf(" %s %d\n", months[month - 1], year);
printf(" Su Mo Tu We Th Fr Sa\n");
int days_of_month = get_days(year, month);
int first_day_of_week = get_day_of_week(year, month);
for (int i = 0; i < first_day_of_week; i++) {
printf(" ");
}
for (int i = 1; i <= days_of_month; i++) {
printf("%3d", i);
if ((first_day_of_week + i) % 7 == 0) {
printf("\n");
}
}
if ((first_day_of_week + days_of_month) % 7 != 0) {
printf("\n");
}
}
第四步:使用示例
以下是一个简单的示例代码,可以编译运行后在命令行输入“./calendar 2021 5”来打印2021年5月的日历。
#include <stdio.h>
char *months[] = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int is_leap_year(int year) {
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
int get_days(int year, int month) {
if (month == 2 && is_leap_year(year)) {
return 29;
} else {
return days[month - 1];
}
}
int get_day_of_week(int year, int month) {
int q = 1;
int m = (month == 1 || month == 2) ? month + 12 : month;
int k = year % 100;
int j = year / 100;
return (q + ((m + 1) * 26) / 10 + k + k / 4 + j / 4 + 5 * j) % 7;
}
void print_calendar(int year, int month) {
printf(" %s %d\n", months[month - 1], year);
printf(" Su Mo Tu We Th Fr Sa\n");
int days_of_month = get_days(year, month);
int first_day_of_week = get_day_of_week(year, month);
for (int i = 0; i < first_day_of_week; i++) {
printf(" ");
}
for (int i = 1; i <= days_of_month; i++) {
printf("%3d", i);
if ((first_day_of_week + i) % 7 == 0) {
printf("\n");
}
}
if ((first_day_of_week + days_of_month) % 7 != 0) {
printf("\n");
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: calendar year month\n");
return 1;
}
int year = atoi(argv[1]);
int month = atoi(argv[2]);
print_calendar(year, month);
return 0;
}
以下是另一个示例代码,可以实现连续输出3个月的日历。注意,需要反复调用get_days和get_day_of_week函数。
#include <stdio.h>
char *months[] = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int is_leap_year(int year) {
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
int get_days(int year, int month) {
if (month == 2 && is_leap_year(year)) {
return 29;
} else {
return days[month - 1];
}
}
int get_day_of_week(int year, int month) {
int q = 1;
int m = (month == 1 || month == 2) ? month + 12 : month;
int k = year % 100;
int j = year / 100;
return (q + ((m + 1) * 26) / 10 + k + k / 4 + j / 4 + 5 * j) % 7;
}
void print_month(int year, int month) {
printf(" %s %d\n", months[month - 1], year);
printf(" Su Mo Tu We Th Fr Sa\n");
int days_of_month = get_days(year, month);
int first_day_of_week = get_day_of_week(year, month);
for (int i = 0; i < first_day_of_week; i++) {
printf(" ");
}
for (int i = 1; i <= days_of_month; i++) {
printf("%3d", i);
if ((first_day_of_week + i) % 7 == 0) {
printf("\n");
}
}
if ((first_day_of_week + days_of_month) % 7 != 0) {
printf("\n");
}
}
void print_calendar(int start_year, int start_month, int num_of_months) {
for (int i = 0; i < num_of_months; i++) {
print_month(start_year, start_month + i);
}
}
int main() {
print_calendar(2021, 5, 3);
return 0;
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用C语言打印月历 - Python技术站