使用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日

相关文章

  • 深入理解golang的异常处理机制

    深入理解golang的异常处理机制 在golang中,异常被称为panic,而异常处理则被称为recover。golang对于异常处理的机制稍微有些不同于其他语言,但是也非常简单易懂。在这篇攻略中,我们将会深入探讨golang的异常处理机制。 什么是panic? panic简单来说,是程序在运行过程中的一种异常状态,类似于Java中的throw和C#中的th…

    C 2023年5月23日
    00
  • Linux/Nginx如何查看搜索引擎蜘蛛爬虫的行为

    要查看搜索引擎蜘蛛爬虫的行为,可以使用Linux系统中的命令行工具,例如使用Nginx的access日志。下面是查看蜘蛛爬虫行为的步骤: 1. 确定Nginx日志路径 默认情况下,Nginx的日志路径为 /var/log/nginx/access.log。但如果在安装Nginx时修改了日志路径,则需要确定正确的路径。 2. 查看日志内容 使用以下命令查看Ng…

    C 2023年5月22日
    00
  • C++中try throw catch异常处理的用法示例

    C++中异常处理是一种用于处理程序运行期间发生的错误或异常情况的机制。一般情况下,C++中的异常处理包括三个关键字:try、throw、catch。 try:try语句块中的代码是需要被监控的代码。当try语句块中的代码抛出异常时,异常会被传递到catch块中进行处理。 throw:throw语句抛出一个异常,它抛出的值可以是任意类型的,包括一个简单的数字类…

    C 2023年5月23日
    00
  • 详解C++异常处理(try catch throw)完全攻略

    作为本站的作者,我非常乐意为你介绍“详解C++异常处理(try-catch-throw)完全攻略”的内容。本篇攻略将涵盖以下主题,包括异常的概念,异常处理基本原则,以及如何使用try-catch块和throw语句等。 异常的概念 在C++程序中,如果发生了意外的错误,比如说磁盘空间不足,用户输入错误的数据等,这些都不是我们程序的预期结果。这时,程序会抛出一个…

    C 2023年5月22日
    00
  • JSON对象转化为字符串详解

    JSON对象转化为字符串详解 在JavaScript编程中,我们经常需要处理JSON对象,并且将JSON对象转化成字符串类型以进行网络传输、文件存储等操作。本文将详细讲解如何将JSON对象转化为字符串类型。 为什么需要将JSON对象转化为字符串类型? 在JavaScript中,JSON对象是一种轻量级的数据交换格式。该格式由对象、属性和值组成,可以被所有支持…

    C 2023年5月23日
    00
  • C语言实现简单的扫雷游戏

    C语言实现简单的扫雷游戏攻略 概述 本攻略介绍如何使用C语言编写简单的扫雷游戏,包括游戏界面的实现、游戏逻辑的实现等。 游戏界面 界面结构 扫雷游戏的界面可以分为两个部分:菜单栏和游戏区域。 菜单栏通常包括开始游戏、重新开始、设置等功能。游戏区域包括网格,每个网格内可能是地雷、数字或空白。玩家需要根据每个网格所显示的数字确定周围的地雷数量,从而判断该网格是否…

    C 2023年5月23日
    00
  • 解决golang json解析出现值为空的问题

    解决golang json解析出现值为空的问题,主要是由于json字段中对应的值为null,而golang在解析json时,会忽略掉null值,导致对应的struct中的该字段值为空白值。以下是解决该问题的完整攻略: 1. 解析为map[string]interface{} 可以先将json解析为map[string]interface{},然后针对需要的字…

    C 2023年5月23日
    00
  • vscode执行npm时的一些错误以及处理办法

    VSCode执行npm的一些错误以及处理办法 在使用VSCode开发过程中,经常需要使用npm来安装和管理依赖包,但有时候我们在执行npm命令时,可能会遇到一些错误,为了帮助大家更好地使用VSCode,下面给大家介绍一些常见的npm错误及解决办法。 1. npm install命令超时 在执行npm install的时候,可能会出现超时错误,此时我们需要设置…

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