C言語を用いてカレンダーの作成をしています。
コード #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define BASEYEAR 2000 /*プロトタイプ宣言*/ int leap_year(int);/*うるう年の場合の関数*/ int day_week(int, int, int*);/*曜日計算の関数*/ void main(void) { /*変数の宣言*/ int year = 0; int month = 0; int firstday = 0; /*データ入力・やり直し*/ while (1) { printf("西暦:"); scanf("%d", &year); if (year >= 1) /*yearが1以上でループを抜ける*/ { break; } printf("西暦は1以上で入力してください。\n"); } while (1) { printf("月:"); scanf("%d", &month); if (month >= 1 && month <= 12) /*monthが1~12の間でループを抜ける*/ { break; } printf("月は1~12の範囲で入力してください。\n"); } int day[12] = { 31,28 + leap_year(year),31,30,31,30,31,31,30,31,30,31 }; /*月末*/ /* 1日の曜日を取得 */ firstday = day_week(year, month, day); /* 曜日の表示 */ printf(" 日 月 火 水 木 金 土 \n"); printf(" -------------------- \n"); /* 1日の曜日まで空白を挿入 */ for (int i = 0; i < (firstday + 6) % 7; i++) { printf(" "); } /* 日付の表示 土曜日(0)で改行 */ for (int i = 1; i <= day[month - 1]; i++) { printf(" %2d", i); if (firstday == 0) { printf("\n"); } firstday = (firstday + 1) % 7; } /* 0を入力で表示を終了します */ int end = 0; do { printf("\n表示を終了する場合、0を入力してください\n"); scanf("%d", &end); rewind(stdin); } while (0 != end); } /*うるう年の場合の関数*/ int leap_year(int year) { if (year % 400 == 0) /*yearが400で割り切れればretun1*/ { return 1; } else if (year % 4 == 0 && year % 100 != 0) /*yearが4割り切れ,0でないとretun1*/ { return 1; } return 0; } /*曜日計算の関数*/ int day_week(int year, int month, int* day) { int yy = 0; /*2000年以降の曜日計算*/ if (BASEYEAR < year) { for (int i = BASEYEAR; i < year; i++) { yy += 1 + leap_year(i) ; } } /*2000年より前の曜日計算*/ else if (year < BASEYEAR) /*1996年からずれている*//*うるう年は+6でなく+7されている*/ { for (int i = year; i < BASEYEAR; i++) { yy += 6 + leap_year(i); } } /* 各月分の日付を足す */ for (int i = 1; i < month; i++) { yy += day[i - 1]; } /* 最後に7で割ると、その月の1日の曜日が求まる */ yy %= 7; return yy; }
C言語始めたての初心者です。
C言語を用いてカレンダーの作成をしています。ツェラーの公式等を使用しないで簡単な形でfor文・if文で作成したいです。
2000年1月を基準として行っています。
アドバイスをいただければ幸いです。
そもそも、基準としているはずの2000年1月時点で結果がずれているので、まずはそちらから合わせることを目標にしてみてはいかがでしょうか。
コメントありがとうございます。曜日計算の関数にある最初のifのfor文内がずれてるという認識でよろしいでしょうか。
2000年1月と入力した際に、どうなるのが正しいか考えてください。2000年1月は基準なのだから、day_week内のyyの値が「yy%=7;」する前の時点で0になるのが正しいはずですが、そうなっていません。day_week内の節目節目でyyの値を確認し、どの処理でyyが0でなくなるのか調べるのがよろしいかと思います。確認方法は、デバッガを使うなり、printfで表示するなり、やりやすい方法でどうぞ。

> C言語を用いてカレンダーの作成をしています。
C の話であればあなたが付けたタグの C# は間違ってます。C のタグがあるのでそれに付け替えてください。
とりあえずコードのご提示にはコードのマークダウン(```だけの行で前後を囲む)を用いるように修正してください。コメントの /* */ の "*" が消えている等でコピペしても正常に動作させられません。
うるう年でズレるのは分かっているはずですから
>/*曜日は1年で1日進む*/
というような前提でやるよりも、単純に2000年1月1日から指定年月まで何日あるかをループで年月の日数を足してそれを7日で割って余りを求めるほうが簡単ではないでしょうか。
>int day[12] = { 31,28 + leap_year(year),31,30,31,30,31,31,30,31,30,31 }; /*月末*/
これは恐らく想像されている(year が変わったら配列の値も変わる)ようには動作しません。
回答3件
あなたの回答
tips
プレビュー