問題文
西暦・月を入力してカレンダーを表示するプログラムを作成せよ。
プログラム全体のことを考える。プログラムの流れとしては、つぎのようになるであろう。
(1)変数の宣言: プログラムの中で使う変数や配列等をすべてここに集めておく。
(2)入力: キーボードから、西暦年の値を読み取る ← scanf( ) 関数
1月から12月まで、以下を繰り返す。
(3)カレンダーの年・月の表示: (例えば、2008年1月 と表示)
(4)各曜日名の表示: 「日 月 火 水 木 金 土」と表示
(5)月の日数の算出: 月の最後の日を計算しておく。(*1~12月以外では誤りとすること)
(6)曜日の算出: 月の初めの日(ついたち)の曜日をツェラー公式で計算しておく。
(7)空列の表示: ついたちの前の空白部分を表示する ← for文 を利用。
(8)各日の表示: 月の各日を順に表示していく ← for文を利用
(土曜の後に改行を入れる)
#include <stdio.h>
int leapYear(int year)
{
if (year%400==0||(year%4==0 && year%100!=0))
{
return 1;
}
else
{
return 0;
}
}
int main(void)
{
int d,year,m,i;
int day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /*1~12月までの各月の日数*/
printf("西暦を入力してください:");
scanf("%d",&year);
printf("月を入力してください:");
scanf("%d",&m);
if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)/*1~12月以外で日数を出そうとした場合*/
{
printf("入力が誤っています。やりなおしてください。\n");
}
else{
if (leapYear(year)==1)/*閏年の場合*/
{
printf("%d年は閏年です。\n",year);
day[1] +=1;
}
else/*閏年でない場合*/
{
printf("%d年は閏年ではありません。\n",year);
}
i = (year+year/4 -year/100 +year/400 + ( 13*m+8 )/5 + 1) % 7; /*西暦~年・1~12月の1日の曜日について考える*/
printf("日 月 火 水 木 金 土\n");
(7)・・・
(8)・・・
}
return 0;
}
手順に沿ってやっていく課題なのですが(7)、(8)の部分の表現の仕方が良く分かりません。(求めた月の日数をカレンダー形式に表示する方法・1日の前に空白を入れる等)
過去の質問も見たのですが、いまいち理解できず・・・orz
どなたかご教授お願いできないでしょうか・・・。
No.3ベストアンサー
- 回答日時:
>(7)、(8)の部分の表現の仕方が良く分かりません。
難しく考えていませんか。
・朔日の前に空白
・土曜( 6 )出力後改行
だけですよね。
-------------------------------------
i01Youbi = Zeller( year, m ); // 0-6
for( i = 0; i < i01Youbi; i++ ) printf( "___" ); // 朔日の前に空白3つ▼×必要分(投稿上 _ としています)
for( i = 1; i <= day[ m - 1 ]; i++ ){
printf( "%3d", i ); // 3桁▲上と同じに
if( 6 == ( ( i - 1 + i01Youbi ) % 7 ) ) printf( "\n" ); // 土曜出力後改行
}
printf( "\n" );
(インデントに全角空白使用)
-------------------------------------
>day[ 1 ] += 1; 確かに 29 になるのですが、
day[ 1 ] = 29; とした方が・・(今回はOKですが・・やがて?)。
#include <stdio.h>
int leapYear(int year)
{
if (year%400==0||(year%4==0 && year%100!=0))/*閏年の判定*/
{
return 1;
}
else
{
return 0;
}
}
int main(void)
{
int year,m,i,d;
int day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /*1~12月までの各月の日数*/
printf("西暦を入力してください:");
scanf("%d",&year);
printf("月を入力してください:");
scanf("%d",&m);
if((m<1) || (12<m))/*1~12月以外で日数を出そうとした場合*/
{
printf("入力が誤っています。やりなおしてください。\n");
}
else
{
if (leapYear(year)==1)/*閏年の場合*/
{
printf("%d年は閏年です。\n",year);
day[1]=29; /*閏年の時は2月の日数が1増える*/
}
else/*閏年でない場合*/
{
printf("%d年は閏年ではありません。\n",year);
}
i = (year+year/4 -year/100 +year/400 + ( 13*m+8 )/5 + 1) % 7; /*西暦~年・1~12月の1日について考える*/
printf("日 月 火 水 木 金 土\n");
d = i;
for(i = 0; i < d; i++) printf("☆");/*一日の前に空白を表示*/
for(i = 1; i <= day[ m - 1 ]; i++)
{
printf("%3d", i);
if(6 == ((i - 1 + d) % 7)) printf("\n");
}
printf("\n");
}
return 0;
}
アドバイスを踏まえてやったつもりです(☆は空白3つ)。プログラム実行結果表示もうまくいったのですが、何故か1月と2月だけ、ずれが発生します。
i01Youbi = Zeller( year, m );の部分を変に変えてしまったのが原因なのでしょうか?この部分だけ良く分からなかったので・・・
No.4
- 回答日時:
> プログラム実行結果表示もうまくいったのですが、何故か1月と2月だけ、ずれが発生します。
それは「うまくいった」とは言いません。
> ツェラーの公式を使う際、1月・2月は前年の13月・14月とみなす、
> という決まりがありませんでしたか?
これへの対応は、どうなっていますか?
#include <stdio.h>
int leapYear(int year)
{
if (year%400==0||(year%4==0 && year%100!=0))/*閏年の判定*/
{
return 1;
}
else
{
return 0;
}
}
int main(void)
{
int year,m,i,d;
int day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /*1~12月までの各月の日数*/
printf("西暦を入力してください:");
scanf("%d",&year);
printf("月を入力してください:");
scanf("%d",&m);
if((m<1) || (12<m))/*1~12月以外で日数を出そうとした場合*/
{
printf("入力が誤っています。やりなおしてください。\n");
}
else
{
if(m<=2)
{
i = ((year-1)+(year-1)/4 -(year-1)/100 +(year-1)/400 + ( 13*(m+12)+8 )/5 + 1) % 7;/*西暦~年、1月・2月の1日について*/
}
else
{
i = (year+year/4 -year/100 +year/400 + ( 13*m+8 )/5 + 1) % 7; /*西暦~年、3~12月の1日について*/
}
if (leapYear(year)==1)/*閏年の場合*/
{
printf("%d年は閏年です。\n",year);
day[1]=29; /*閏年の時は2月の日数が1増える*/
}
else/*閏年でない場合*/
{
printf("%d年は閏年ではありません。\n",year);
}
printf("日 月 火 水 木 金 土\n");
d = i;
for(i = 0; i < d; i++) printf(" ");/*一日の前に空白を表示*/
for(i = 1; i <= day[ m - 1 ]; i++)
{
printf("%3d", i);
if(6 == ((i - 1 + d) % 7)) printf("\n");
}
printf("\n");
}
return 0;
}
> ツェラーの公式を使う際、1月・2月は前年の13月・14月とみなす、
という決まりがありませんでしたか?
すみません・・・すっかり忘れていました。
上記のとおりsuncionさんの言うとおりやってみたら、1月と2月も問題なく表示できるようになりました!
貴重な時間を割いてもらって、お手数をおかけしました。そしてありがとうございました!
No.2
- 回答日時:
(7)より、(8)を先に考えた方が楽です。
まずは、1日が日曜日の場合を考えてみてください。
日~土まで表示するには1~7を表示します。
カレンダーの様にするには、土曜日にあたる7、14、21、28で次の行に移動し続けて数字を表示(7なら、次の行は8~)する方法を考えてください。
この部分ができると、次は1日を表示する位置を求めます。曜日を求める式はありますから、その曜日の前までは空白を表示していけばいいことになります。
そして、(8)の処理を日曜から1日が始まらない場合でも動作するように変更すればOKです。
それと
>if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)/*1~12月以外で日数を出そうとした場合*/
は見難いので、if((m<1) || (12<m))のようにすべきです。
ちなみに「&」ではなく「&&」です
No.1
- 回答日時:
ツェラーの公式を使う際、1月・2月は前年の13月・14月とみなす、
という決まりがありませんでしたか?
> if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)
このif文、美しくないですね。それに、& じゃなくて && です。
もっと単純に、
if (m < 1 || 12 < m)
でいいんじゃないですか。
> if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)
このif文、美しくないですね。それに、& じゃなくて && です。
もっと単純に、
if (m < 1 || 12 < m)
でいいんじゃないですか。
>>ご指摘ありがとうございます。今度からは気をつけます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
よくある 『 第○(1・2・3・4・...
-
エクセルで毎月第2週日の水曜日...
-
[Excel] ある日の曜日が当月の"...
-
月の第一週とは
-
毎○曜日って、使いますか?
-
時計の曜日がいつのまにか違う
-
週2回のペースって だいたい何...
-
ユーザー定義の(aaa)
-
6月の第2 第4火曜日は何日...
-
for a week tomorrowはどういう...
-
ディズニーシー平日の混み具合...
-
曜日と曜の使い分けがわかりま...
-
第○曜日であるかを取得する関数
-
日付から曜日を求めたい
-
Excelで第一〇曜日を求める方法...
-
入力した日は何曜日か
-
指定した日付から曜日を求める。
-
F-BASIC ツェラーの公式...
-
c言語の質問です。 ある月のカ...
-
日本語問題 昨日は何曜日ですか...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
月の第一週とは
-
週2回のペースって だいたい何...
-
エクセルで毎月第2週日の水曜日...
-
エクセルで 自動的に◯や数字を...
-
よくある 『 第○(1・2・3・4・...
-
毎○曜日って、使いますか?
-
VBA。複数のChangeイベントをま...
-
[Excel] ある日の曜日が当月の"...
-
毎週同じ曜日にラブホに行くと...
-
今週とは何曜日から何曜日まで...
-
Excelで第一〇曜日を求める方法...
-
曜日を求めるプログラムはどう...
-
曜日のなぞ
-
土曜日の26時って何曜日の何時...
-
第○曜日であるかを取得する関数
-
日本語問題 昨日は何曜日ですか...
-
一年の第何週目であるかを判断...
-
日付から曜日を求めたい
-
指定曜日にMsgBox表示は可能で...
-
Excel関数で当月の第一日曜日の...
おすすめ情報