0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カレンダープログラム2

Last updated at Posted at 2026-01-08

目的

  • 前回の課題を解決したプログラムを実装した
    1. 各月の日数を格納した配列daysInMonth[]が二度定義されている(main関数とcalcDayOfWeek関数)
      • 入力した月の日数を返す関数(findDaysInMonth関数)を新規に作成する
    2. isLeapYear関数は閏年か否や(true/false)をreturnしている
      • そのため呼び出し元で、その戻り値に基づいて着目している年が365日なのか366日なのかを割り振るという二度手間なプロセスになっている
      • isLeapYear関数のように閏年 or Nor(true/false)を返すのではなく、引数として入力された年に対して365日あるいは366日を返す関数(findDaysOfYear関数)を新規に作成する
  • ついでに、カレンダーを表示する部分を新しい関数(dispCalendar関数)に分離した

ソースコード

#include <stdio.h>

// 閏年判定関数
// 4で割り切れてかつ100で割り切れない、または400で割り切れる年は閏年
int isLeapYear(int year){
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 1年の日数を判定する関数
// 閏年の場合は366を返しそれ以外は365を返す
int findDaysOfYear(int year){
    if(isLeapYear(year)){
        return(366);
    }else{
        return(365);
    }
}

// 月ごとの日数を返す関数
// 閏年ならば2月は29日にする
int findDaysInMonth(int month, int year){

    // 各月の日数(平年), 月と要素番号を合わせるために0番目に0を格納する
    int daysInMonth[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    
    // 閏年の場合は2月を29日とする
    if(isLeapYear(year)){
        if(month == 2){
            daysInMonth[month] = 29;
        }
    }

    return(daysInMonth[month]);

}

// 引数の日付の曜日を計算する
// 戻り値は曜日番号 0:Sunday, 1:Monday, 2:Tuesday, 3:Wednesday, 4:Thursday, 5:Friday, 6:Saturday
// -> 2000/1/1からの日数を計算することにより曜日番号を求める
// (c.f. 2000/1/1 Saturday)
int calcDayOfWeek(int year, int month, int day){

    int y, m;
    // 基準とする2000/1/1からの日数
    int totalDays = 0;
    // 曜日番号 0:Sunday, 1:Monday, 2:Tuesday, 3:Wednesday, 4:Thursday, 5:Friday, 6:Saturday
    int dayOfWeekNum;

    if(year < 2000){
    // 1999年以前のカレンダーを計算する場合
    // この場合は1999/12/31から求める日付まで遡るように計算する
    // 例として1990/5/5の曜日を求める場合を考える

        // 1999~1991までの日数を足す
        for(y = 1999; y > year; y--){
            // 閏年ならば1年366日, それ以外は365日を足す
            totalDays += findDaysOfYear(y);
        }

        // 1990年の12月から6月までの日数の合計を求める
        for(m = 12; m > month; m--){
            totalDays += findDaysInMonth(m, year);
        }
        // 5月末から5/5までの日数を加える
        totalDays += findDaysInMonth(m, year) - day + 1;

        dayOfWeekNum = 6 - totalDays%7;
    
    }else{
    // 2000年以降のカレンダーを計算する場合
        for(y = 2000; y < year; y++){
            // 閏年ならば1年366日, それ以外は365日を足す
            totalDays += findDaysOfYear(y);
        }

        // yearにおいてが求める日付の前の月までの日数を求める
        for(m = 1; m < month; m++){
            totalDays += findDaysInMonth(m, year);
        }
        totalDays += day - 1;

        // 基準日である2000/1/1の曜日番号も足す
        totalDays += 6;
        dayOfWeekNum = totalDays%7;
    }
    
    return (dayOfWeekNum);

}

// 指定年月のカレンダーを表示
void dispCalendar(int year, int month, int firstDay){

    int daysOfCertainMonth = findDaysInMonth(month, year);

    // カレンダーの見出し
    printf("\n< %d-%02d calendar >\n", year, month);
    printf("Sun Mon Tur Wed Thu Fri Sat\n");

    // カレンダー最初の行に半角スペース4文字の空白を出力
    for (int i = 0; i < firstDay; i++) {
        printf("    ");
    }

    // 各日の出力
    for (int day = 1; day <= daysOfCertainMonth; day++) {
        printf(" %2d ", day);

        // 土曜ごとに改行
        if ((firstDay + day) % 7 == 0) printf("\n");
    }
    printf("\n"); // 最後に改行

}

int main(void){
    
    int year, month;

    // 年の入力
    printf("Input the year: ");
    scanf("%d", &year);
    // 月の入力
    printf("Input the month: ");
    scanf("%d", &month);
    
    if(year < 1873){
        printf("Only compatible from 1873.\n");
        return(0);
    }
    if(month < 1 || 12 < month){
        printf("input the month in 1-12.\n");
        return(0);
    }

    // 指定月の1日が何曜日かを計算する
    int firstDay = calcDayOfWeek(year, month, 1);

    // 指定年月のカレンダーを表示
    dispCalendar(year, month, firstDay);

    return(0);
}

出力結果


Input the year: 2026
Input the month: 1

< 2026-01 calendar >
Sun Mon Tur 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  31 


Input the year: 1990
Input the month: 5

< 1990-05 calendar >
Sun Mon Tur 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  31 
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?