• 締切済み

C言語初心者です。

C言語初心者の者です・・。カレンダーを表示するというプログラムを 作成して下さい。という問題でソースが途中まで出来ていてこれを元に 作成するみたいなのですが、今まで、こちらのサイトで同じような質問は無いかなぁと検索してみたのですが、年数やうるう年の計算もされていて、どこをどの様に変えれば良いのかも分かりません。どなたか教えて頂けないでしょうか? 〖問題〗 以下のように、カレンダーを表示するプログラムを書いてください。 int main (void) { /* 1月表示 */ dispCalender(1); return 0; } void dispCalender(int month) { /* 2007年:月毎の最終日を管理する配列 */ int lastday[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,31}; /* 2007年:各月が何曜日から始まるか管理する配列 */ int week[12] = {1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6} /* ※0:日、1:月、2:火 ・・・ 6:土 */ (ここにいっぱいコード書く) } (実行結果) --------------------- [2007年1月] --------------------- 日 月 火 水 木 金 土 --------------------- 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ---------------------

noname#33936
noname#33936

みんなの回答

  • maguro999
  • ベストアンサー率21% (59/273)
回答No.3

根本的問題として ・このプログラムだと2007年しかカレンダー化できないけどいいのか? 回避方法としてツェラーの公式で曜日取得する。 ・同じく閏年計算ができてない 閏年計算を入れる。 で質問者の書いたコードで根本的に変なところ switch文。 そもそも過大なので丸投げに近い質問ですし ソースを書いたら意味無いのでヒントとして 1.一週間は7日。それをループでまわす変数0~7を繰り返す。 もしくはずっと+1していってもいいが7割で余りから計算する変数 2.実際の日付をカウントして変数lastday[]までする変数。 3.その月の始まりの曜日まで1.の変数を単にプラスしてまわして2.の変数を1.の曜日から初めてカウントし始める。 それを気をつければ大して難しいものではないです。

noname#33936
質問者

お礼

どうもありがとうございました!! ヒントがとても役に立ちました!!! きちんと、ソースにできそうなので大丈夫です!! 回答ありがとうございました。

  • DT200
  • ベストアンサー率38% (63/164)
回答No.2

授業で出された課題でしょうか? とりあえず、解らないなりに自分で考えたコードを示してから質問すべきでは。 以下に、処理の流れを示します。後は自身で努力してください。 ======== 1. パラメータmonthが1~12の範囲にあるか判定し、範囲外ならエラーメッセージを   表示してリターンする。(これはなくても可) 2. タイトルの部分を表示する。ここはprintfで表示するだけなので難しくないと思います。 3. その月が何曜日から始まるかはweek[]で指示されているので、その分をfor分を使いループし   3文字分の空白を出力する。注意点は改行しないこと。 4. 曜日にweek[]の値を設定(その月の)。 5. その月の最終日lasetday分をfor分でループする。 5-1. 日付を2桁+1文字の空白で表示する。ここでも改行はしない。 5-2. 4.でセットした曜日に+1する。 5-3. 曜日が土曜日(=6)なら改行する。曜日をクリア(日曜日する)する。 6. 月の最終の日付まで表示して、その日が土曜日でなければ改行する。 7. 最後の ------- を表示する。 8. リターン =========== 注意: int week[12] = {1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6} にセミコロンが抜けている。 この問題は2007年限定として出題されているようなので、閏年の計算は不要です。

noname#33936
質問者

お礼

回答ありがとうございます! すみませんでした・・。今の段階で出来ているソースは 下記の物です。 #include<stdio.h> void dispCalender(int month); int main (void) { /* 1月表示 */ dispCalender(1); return 0; } void dispCalender(int month) { int i,j=0; /* 2007年:月毎の最終日を管理する配列 */ int lastday[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,31}; /* 2007年:各月が何曜日から始まるか管理する配列 */ int week[12] = {1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6}; /* ※0:日、1:月、2:火 ・・・ 6:土 */ printf("---------------------\n[2007年1月]\n---------------------\n日 月 火 水 木 金 土\n---------------------\n"); for(i=0;i<lastday[j];i++){ switch(week[12]) printf("%02d ",i+1); if(i%7==6){ printf("\n"); } } } <今実際にコンパイルするとこの状態です。> --------------------- [2007年1月] --------------------- 日 月 火 水 木 金 土 --------------------- 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 問題なのが、1月は、月曜日から始まるのに このソースだと日曜日からになってしまうからです。 質問がきちんと出来ておらず、すいませんでした。

  • a-gamyl
  • ベストアンサー率32% (17/53)
回答No.1
noname#33936
質問者

お礼

早い対応ありがとうございました!! 参考サイト見て勉強してみます(>∀<)★☆

関連するQ&A

  • カレンダーのC言語プログラムを教えてください!

    西暦年と月を入力すると、その年月のカレンダーが出てくる万年カレンダーのC言語プログラムを教えてください! その出力結果が 2***年 *月 月 火 水 木 金 土 日 月 火 水 木 金 土 日 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 というように二週間ごとに表示するもので、 うるう年の判別ができるものになるようにしたいのですが。 年=n月=g で入力するものを作りたいんです。 よろしくお願いします!!!(>_<)

  • C言語でのカレンダープログラミングについて。

    今、C言語でカレンダーについてのプログラミングを行っています。 まず月を入力し表示させる。 その年がうるう年かどうか判定させる。 日曜~土曜を表示し、指定した月の日数を曜日に合わせて表示させる。 2008年1月1日は火曜日。 という事実を利用してよい。 という条件で、うるう年かの判定はあるものの年は2008年で固定です。 曜日、指定した月の日数を出すところまでいきましたが。 曜日に合わせて出す事ができません。 今は1月に合わせて、1日が火曜日のところに出るように配置してます。 が、次の週になったときにどのように改行指定すればいぃのかわりません。 また、来月以降の月初めの曜日指定もわからないです。 途中までのプログラムはこれです。 醜いかもしれませんが。 #include <stdio.h> int main(void) { int year=2008; int month,hantei=0,a,b,c; int uru[12]={31,29,31.30,31,30,31,31,30,31,30,31};/*うるう年の時の各月ごとの日数*/ int normal[12]={31,28,31,30,31,30,31,31,30,31,30,31};/*通常の年の各月ごとの日数*/ printf("表示させる月を入力してください。:"); scanf("%d",&month); if(year%4==0||year%100==0||year%400==0) { hantei=1;/*その年がうるう年かどうかを判定し、うるう年なら「hantei」に「1」が代入*/ } if(hantei==1)/*うるう年の場合。*/ { printf("%d年 %d月\n",year,month); printf("%d日\n",uru[month-1]); } else/*通常の年の場合。*/ { printf("%d年 %d月\n",year,normal[month-1]); printf("%d\n",normal[month-1]); } printf("日 月 火 水 木 金 土\n");/*曜日*/ if(hantei==1)/*うるう年の場合*/ { for(b=0;b<=7;b++) { printf(" ");/*火曜日のところまでスペースを空ける*/ } for(c=1;c<=uru[month-1];c++)/*日数表示*/ { printf("%2d ",c); } } return(0); } まだあまりC言語に詳しくないので、簡単に説明できる範囲で御願いします。 説明がわかりにくいかもしれませんが、すいません。

  • C言語初心者です

    私は今C言語のフローチャートを勉強しているのですが なかなかうまくいきません。他のサイトや本などではサンプルが載ってたりするのですが実際に書いてみると雑な感じになってしまいます カレンダー表示でフローチャートを作成するとして 年 月 日の宣言と初期化 ↓ 月の末日配列の宣言と初期化 曜日の配列宣言と初期化 ↓ 閏年の判定 ↓ 前月までの日数 ↓ 前月と前年度 今月の日数の合計 ↓ 曜日計算 (総日数から7で割った余り) ↓ 出力 ↓ 終了 といった感じになりました。全体的に明確にしたいのですが どんな感じにすればいいのかわかりません 例えば 月の末日の配列宣言と初期化、曜日の配列宣言と初期化 この部分を明確にするにはどう表現したらいいのでしょうか? アドバイスの方よろしくおねがいします。

  • C言語で以下のようなプログラムを組むには

    C言語で以下のようなプログラムを組むには C言語初心者です。 1900年~2100年で閏年になる年を拾い出し表示するプログラムを作成するにはどのようにすればよろしいのでしょうか? 1.西暦年が4で割り切れる年は閏年 2.ただし、西暦年が100で割り切れる年は平年 3.ただし、西暦年が400で割り切れる年は閏年 4で割り切れて100で割り切れない年と400で割り切れる年をピックアップすればよいので #include <stdio.h> int main(void) { int i, a, b; for(i = 1900; i<=2100; i++) !i % 4; printf("%d ", i); putchar('\n'); return (0); } ここまでは何となく思いついたのですが進めなくなっちゃいました。 よろしくお願いします。

  • C言語でのカレンダーの表示について質問です

    VisualStudioを使ってC言語でコンソールアプリケーションのカレンダーを作っています。 やりたいことは以下の通りです。 プログラムを起動すると、現在の月を中央に三ヶ月分のカレンダーを表示。 Lキーでカレンダー全体を一ヶ月前に変更 Rキーで一ヶ月後に変更 Dキーで三ヶ月前に変更 Uキーで三ヶ月後に変更 Aキーで一年前に変更 Bキーで一年後に変更 起動時にカレンダー表示するのはできているんですが、Rでカレンダーを進めていくと12月の次が13月、次が0月、その次が1月となってしまい、日付も上手いこと表示されません。 L,D,U,でも同じようになります。 また、A,Bで年を変えると日付が正確に表示されないです。 これらを正しく表示させる方法をご教授いただけますでしょうか。 #include <stdio.h> #include <conio.h> #include <time.h> #define KEY_ESC (0x1b) // エスケープ #define KEY_L (0x6c) // L #define KEY_D (0x64) // D #define KEY_R (0x72) // R #define KEY_U (0x75) // U #define KEY_A (0x61) // A #define KEY_B (0x62) // B time_t timer; // 現在の時刻 struct tm local; // 地方時 int curr_year; // 現在の年 int curr_mon; // 現在の月 int input; // どのキーが入力されたか int calendar[12][6][7]; // 月、最大の週、1週間 int year; // 年 int month; // 月 int day; // 日 int nweek; // その月が何周あるか int nday; // その月が何日まであるか int day_of_week; // その月が何曜日から始まるか void CalendarDisplay(void); void CalendarSet(void); void DayOfWeek(int, int, int); void NumOfDay(int); void KeyOperat(int); int LaepYear(int, int); int Zeller(int, int, int); int main(void) { CalendarDisplay(); while (1) { printf("ESCキーで終了\n\n"); input = _getch(); if(input == KEY_ESC) { break; } else if(input == KEY_L || input == KEY_D || input == KEY_R || input == KEY_U || input == KEY_A || input == KEY_B) { KeyOperat(input); } } return 0; } // カレンダーの表示 void CalendarDisplay(void) { // 現在時刻を取得 timer = time(NULL); // 地方時に変換 localtime_s(&local, &timer); // 現在の年 curr_year = local.tm_year + 1900; // 現在の月 curr_mon = local.tm_mon + 1; CalendarSet(); } // 当月とその±1の月を設定 void CalendarSet(void) { for (month = curr_mon-1; month <= curr_mon+1; month++) { // 12月を超えたら次の年に if(curr_mon > 12) { curr_mon = 1; month = 1; curr_year += 1; } // 1月を超えたら前の年に else if(curr_mon < 1) { curr_mon = 12; month = 12; curr_year -= 1; } // その月が何日まであるか求めて代入 nday = LaepYear(curr_year, month); // その月が何曜日から始まるか day_of_week = Zeller(curr_year, month, 1); nweek = 0; for (day = 1; day <= nday; day++) { calendar[month-1][nweek][day_of_week] = day; //printf("day-> %d ", day); if (++day_of_week == 7) { day_of_week = 0; nweek++; } } } DayOfWeek(month, curr_mon, curr_year); } // 月と曜日の表示 void DayOfWeek(int m, int cur_m, int cur_y) { for (m = cur_m-1; m <= cur_m-1; m++) { printf("%d%6d月%16d%6d月%16d%6d月\n" "日 月 火 水 木 金 土  " "日 月 火 水 木 金 土  " "日 月 火 水 木 金 土\n", cur_y, m, cur_y, m + 1, cur_y, m + 2); NumOfDay(&calendar[m-1]); } } // 日数の表示 void NumOfDay(int calendar[][6][7]) { int max_w = 0, nmon = 0, w = 0; // その月の最大週の間 for (max_w = 0; max_w < 6; max_w++) { // 3ヶ月分表示 for (nmon = 0; nmon < 3; nmon++) { for (w = 0; w < 7; w++) { if (calendar[nmon][max_w][w]) { printf("%2d ", calendar[nmon][max_w][w]); } else { printf(" "); } } printf(" "); } printf("\n"); } } // キー操作でカレンダーの表示を変える void KeyOperat(int input) { do { switch(input) { case KEY_L: curr_mon -= 1; break; case KEY_R: curr_mon += 1; break; case KEY_D: curr_mon -= 3; break; case KEY_U: curr_mon += 3; break; case KEY_A: curr_year -= 1; break; case KEY_B: curr_year += 1; break; default : input = !input; break; } } while(!input); CalendarSet(); } // うるう年の判定 int LaepYear(int y, int m) { const int num_day[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (m == 2 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) { return 29; } return num_day[m - 1]; } // ツェラーの公式から曜日を求める int Zeller(int y, int m, int d) { int dow;   // 1月と2月の場合、それぞれ前年の13月、14月とする if(m == 1 || m == 2) { y--; m = m + 12; } dow = (y + y/4 - y/100 + y/400 + (13*m+8)/5 + d) % 7; return dow; }

  • C言語でのカレンダー作成

    今、C言語でカレンダーを表示させるプログラムを作成しています 西暦と月を入力すると、その年、その月の1ヶ月分のカレンダーが表示されるプログラムを作りました そこで、次は入力した月から3ヶ月分のカレンダーを表示させるプログラムを作成したいのですが、どなたか教えてくださいませんか? 配列を使う方法や文字列など色々な方法があると伺って、どの方法が作りやすいのかわからないんです・・・ borland c を使用しています

  • C言語の問題です

    うるう年も含めて、西暦年における各月の日数を表示せよ。 キーボードからの入力は、年と月、の2つの値。 例 2007 6   2007 2   2000 2   2100 2 画面にはその月の日数を表示する。 例 入力が 2007 6 に対して、画面に 「2007年6月の日数は30である」 と表示する。 間違って入力に対しては、再入力を促すようにすること。 プログラムに配列を必ず使うこと。 ソースプログラムと実行画面のコピーをWordファイルに貼り付けて提出すること。 うるう年の表示と年を選ばせることができません。 助けてください!

  • C言語で3次元配列を使い一年分のカレンダーを作成

    C言語課題で「三次元配列を定義して、与えられた年の1年間分のカレンダーを作成する」という課題があるのですが三次元配列を使い一年分のカレンダーがなかなか出来ません。 教えていただけるとありがたいです。 どうかよろしくお願いします!!!! 現状はこの状態です。 #pragma warning(disable:4996) #include <stdio.h> #define WEEK 6 enum M_LIST { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, N_MONTH }; enum W_LIST { SUN, MON, TUE, WED, THU, FRI, SAT, N_WEEK }; char *weekday[] = { "日,月,火,水,木,金,土" }; //曜日 int mday[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //各月の日数 /*プロトタイプ宣言*/ int monthday(int year); void karenda(int total); /*メイン*/ void main(void) { int year; printf("西暦を出力"); scanf("%d", &year); //年度の出力 karenda(monthday(year)); } /*求める月の前月までの総日数*/ int monthday(int year) { int total = 0; /*求める年の前年までの総日数を求める*/ total = (((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400) + 1); /*うるう年の日数*/ if ((year % 4) == 0 && (year % 100) != 0 && (year % 400) == 0)mday[FEB] = 29; { } return total; } /*カレンダー*/ void karenda(int total) { int month, week, day; int box = total % 7; char cal[N_MONTH][WEEK][N_WEEK]; //3次元配列の宣言 for (month = 0; month < N_MONTH; month++) { printf("%d\n", (month + 1)); //月を入力 for (week = 0; week < WEEK; week++) { for (day = 0; day < N_WEEK; day++) { if (day < box){ printf(" "); } } } } } よろしくお願いします。

  • 西暦・月からカレンダーを表示

    問題文 西暦・月を入力してカレンダーを表示するプログラムを作成せよ。 プログラム全体のことを考える。プログラムの流れとしては、つぎのようになるであろう。  (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 どなたかご教授お願いできないでしょうか・・・。

  • C言語について。初心者です。

    参考書の問題で、「整数値以下である正の偶数を照準に表示するプログラムを作成せよ」 例)整数を入力してください:19   2 4 6 8 10 12 14 16 18 とあり、自分で以下のプログラムを作ってみたのですが「222222・・・・・・・・・・・・・・・・・・」となるだけです。どう変えればちゃんと表示されるようになりますか?ちなみにwhile文を使うのが条件です。 #include<stdio.h> int main(void) {       int na; int nb=0; printf("整数を入力してください。:"); scanf("%d",&na); while(nb<na) printf("%d",nb+2); putchar('\n'); return 0; }

専門家に質問してみよう