使用C语言打印月历

使用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技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 理光C2551彩色复印机怎么扫描文件?

    下面是关于“理光C2551彩色复印机怎么扫描文件”的详细攻略: 步骤一:连接网络 首先,确保你已经在正确的网络环境中,你需要连接到理光C2551彩色复印机所在的网络,才能进行扫描操作。 步骤二:将文件放入扫描仪上 在理光C2551彩色复印机上找到扫描仪,打开其盖子,并将要扫描的文件放在玻璃底部。注意,如果有多页文件需要扫描,需要一张一张的扫描。 步骤三:选择…

    C 2023年5月23日
    00
  • 使命召唤手游怎么赚c币 C币获取方法一览

    使命召唤手游怎么赚C币:C币获取方法一览 什么是C币? C币是使命召唤手游中的虚拟货币,可以用来购买游戏内道具和装备。 C币获取方法 1. 完成任务 游戏中会有一些每日和成就任务,每完成一项可获得一定数量的C币作为奖励。在任务界面查看任务并完成就可以领取奖励。 2. 参加活动 游戏官方会举办一些活动,参加活动并完成指定要求可以获取C币奖励。活动类型包括临时活…

    C 2023年5月23日
    00
  • Javascript的字符串方法详解

    JavaScript提供了丰富的字符串方法以便进行字符串的操作和处理。在本攻略中,我将对JavaScript的字符串方法进行详解,包括方法的介绍、使用方法、示例说明等,并提供示例代码以便读者更好的理解。 一、JavaScript字符串介绍 JavaScript字符串是一种常见的数据类型,用于保存一组字符。字符串可以使用双引号或单引号来定义,如下所示: con…

    C 2023年5月23日
    00
  • C++ 轻量级对象JSON序列化实现详情

    C++ 轻量级对象JSON序列化实现详情 为什么需要JSON序列化 在程序开发过程中,我们通常需要将内存中的数据序列化并存储到文件或者网络中进行传输。JSON作为一种轻量级的数据交换格式,因其具有易读性、易存储、易解析等优点,被广泛应用于前后端数据交互、移动设备数据传输等领域。C++社区相关的JSON库也有很多,但有些过于庞大,并不适用于轻量级数据的处理。因…

    C 2023年5月22日
    00
  • C++实现寝室卫生管理系统

    C++实现寝室卫生管理系统 1. 系统需求分析 在实现寝室卫生管理系统时,我们需要明确系统的需求和功能。一个基本的寝室卫生管理系统应该包括以下功能: 管理员登录:管理员需要进行身份验证,才能进行管理操作; 学生信息录入:管理员可以添加、修改、删除学生信息; 寝室卫生评分:管理员需要对寝室进行卫生评分,并记录下评分结果; 查询寝室卫生:学生可以通过系统查询自己…

    C 2023年5月23日
    00
  • C++实现中值滤波的示例代码

    下面我将为您详细讲解C++实现中值滤波的示例代码的完整攻略。 什么是中值滤波? 中值滤波是一种基本的数字图像处理方法,它是一种非线性滤波器,可以消除图像中的噪声,保持边缘细节。中值滤波的原理是对滤波器窗口中的像素点进行排序,然后取中间的数值作为滤波结果。通常情况下,中值滤波器的窗口大小是一个奇数,如3×3、5×5等等。 C++中值滤波示例代码 在C++中实现…

    C 2023年5月23日
    00
  • 逍遥自在学C语言 | 第一个C语言程序 九层之台起于垒土

    一、人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 —— 自在。 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。 二、C语言简介 C语言是一种高级语言,运行效率仅次于汇编,支持跨平台 C语言是学习其他高级语言的基础,如C++、Java和Python 三、编程环境 1、在线编译 百度搜索C语言在线编译,会发现有很多在线编译工具 这里以菜鸟工…

    C语言 2023年4月18日
    00
  • C语言函数多个返回值方式

    C语言函数多个返回值方式 在C语言中,函数通常只能返回一个返回值。这可能会限制一些操作的实现,特别是在需要返回多个值的情况下。然而,C语言提供了多种方式来解决这个问题。 方式一:结构体 一种实现方式是通过使用结构体返回多个值。结构体通常定义了相​​关字段,而每个字段都可以看作是一个返回值。 typedef struct { int a; char b; fl…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部