UNIXのcalコマンドもどき。

C言語を思い出すために書いてみた。所要時間1時間。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// メイン関数
int main(int argc, char* argv[]) {
    // today変数にNULLをセットする
    time_t today = time(0);
    // localtimeはNULLを現在時刻として解釈する
    struct tm* day = localtime(&amp;today);
    // 2020/7/13 → 2020/7/1に変更する
    day->tm_mday = 1;

    // プログラム開始時の引数が1個のとき (./cal 7)
    if (argc > 1) {
        // "7" -> 7
        int month = atoi(argv[1]);
        if ( month == 0 ) {
            fprintf(stderr, "Can't parse month text.\n");
            return 1;
        }
        day->tm_mon =  month - 1;
    }
    // プログラム開始時の引数が2個のとき (./cal 7 2020)
    if (argc > 2) {
        int year = atoi(argv[2]);
        if ( year == 0 ){
            fprintf(stderr, "Can't parse year text.\n");
            return 1;
        }
        day->tm_year = year - 1900;
    }

    // カレンダーを表示させたい月をdayに設定する
    time_t st = mktime(day);

    char buf[256];
    strftime(buf, sizeof(buf), "%Y/%m", day);
    printf("       %s\n", buf);
    printf("Su Mo Tu We Th Fr Sa\n");

    // 1日までは空っぽ文字で表示しておく
    for ( int i = 0; i < day->tm_wday; ++i ) {
        printf("   ");
    }

    // カレンダー表示対象の月を覚えておく
    int month = day->tm_mon;

    // dayがカレンダー表示対象の月の間だけ出力する (翌月になったらwhileから抜ける)
    while (month == day->tm_mon) {
        printf("%2d ", day->tm_mday);
        if ( day->tm_wday == 6 ) {
            printf("\n");
        }
        // dayに1日足す
        day->tm_mday += 1;
        st = mktime(day);
        day = localtime(&amp;st);
    }

    printf("\n");
    return 0;
}