这个程序怎么写?初学者等

本来写了一个,但是运行有问题,所以重新求一个,月份之间老是少一天,然后改程序之后,月份第一天是0,但是其他日期是对的,不太理解

img

参考下面的链接,修改了了一下,可以打印出题目所需要的日历。
参考链接:
c语言编写程序“输入任意一个年份和月份,打印当月日历。”_zhao_miao的博客-CSDN博客

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
//https://ask.csdn.net/questions/7782335?spm=1005.2025.3001.5141
int mon[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
//判断闰年
int isleap(int year)
{
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        return 1;
    else
        return 0;
}
//年份的第一天
int first_day_of_year(int year)
{
    int base_year = 2000;  //定义一个基准年2000年
    int first_day = 6;     //基准天:200011号是星期6
    int i = 2000;
    int total = 0;          //天数总和
    for (i = base_year; i < year; i++)
    {
        total = total + 365 + isleap(i);  //isleap函数用于判断年份是否是闰年,如果是返回1,不是返回0
    }
    return (total+first_day)%7;
}
//月份第一天
int first_day_of_month(int year, int month, int first_year)
{
    int total = 0;  //天数和
    int i = 0;
    for(i = 1; i < month; i++)
    {
        total = total + mon[isleap(year)][i];
    }
    return (total + first_year) % 7;
}
//展示日历
void show(int year,int  month, int first_month)
{
    int i = 0;
    printf("SUN  MON  TUE  WED  THU  FRI  SAT\n");  //修改了这里 
    for (i = 0; i < first_month; i++)   //修改了这里 
    {
        printf("     ");     //月份第一天是从first_month开始的,所以首先打印first_month-1个空格
    }
    
   // int firstLine = 0;
    for (i = 1; i <= mon[isleap(year)][month]; i++) //修改了这里 
    {
        printf("%-5d", i);
        if ((first_month+i) % 7 ==0) //如果(数字+空格数)%7==0,则换行
        {
            //printf("i=%d,first_month=%d,mon[isleap(year)][month]=%d\n",i,first_month,mon[isleap(year)][month]);
            printf("\n");
        //    firstLine=1;
        }
        
//        if(i==mon[isleap(year)][month]-1){
//            
//        }
//        if(firstLine==1&&((first_month-1+i) % 7 ==0)){
//            printf("\n");
//        }
            
    }
    printf("\n");
}
int main()
{
    int year, month;
    printf("年-月:");  //输入你想打印的年份
    scanf("%d-%d", &year, &month);
    int first_year = first_day_of_year(year);//年份第一天
    int first_month = first_day_of_month(year, month, first_year);//月份第一天
    show(year, month, first_month);
    system("pause");
    return 0;
}

img

输出自行实现,
具体了解可搜索基姆拉尔森计算公式和蔡勒公式


// Week = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1) mod 7
// 其中: d为几号,m为月份,y为年份
int Date(int y,int m,int d)
{
    if(m==1||m==2){//一二月换算
        m+=12;
        y--;
    }
    int week = (d + 2*m +3*(m+1)/5 + y + y/4 - y/100 + y/400 + 1)%7;
    return week;//其中1~7表示周一到周日
}
#include <ctime>
#include <iomanip>
#include <iostream>

int main() {
  const char *months[] = {"January",   "February", "March",    "April",
                          "May",       "June",     "July",     "August",
                          "September", "October",  "Novement", "December"};
  const char *weekdays[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

  int year, month;
  char ch;
  std::cin >> year >> ch >> month;
  std::cout << std::setw(10) << std::left << months[month - 1] << std::setw(23)
            << std::right << year << '\n';
  for (int i = 0; i < 7; i++)
    std::cout << std::left << std::setw(5) << weekdays[i];
  std::cout << '\n';
  std::tm tm{};
  tm.tm_year = year - 1900;
  tm.tm_mon = month - 1;
  for (int i = 1; i <= 31; i++) {
    tm.tm_mday = i;
    std::mktime(&tm);
    if (tm.tm_mon != month - 1)
      break;
    if (i == 1 && tm.tm_wday != 0)
      for (int j = 0; j < tm.tm_wday; j++)
        std::cout << std::setw(5) << " ";
    std::cout << std::setw(5) << i;
    if (tm.tm_wday == 6)
      std::cout << '\n';
  }
  std::cout << '\n';
  return 0;
}
$ g++ -Wall main.cpp
$ ./a.out
2022-02
February                     2022
SUN  MON  TUE  WED  THU  FRI  SAT  
          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   
$ ./a.out
2022-09
September                    2022
SUN  MON  TUE  WED  THU  FRI  SAT  
                    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