C言語で作成した万年カレンダーのプログラムがエラーになる件について

このQ&Aのポイント
  • C言語で作成した万年カレンダーのプログラムがエラーになります。
  • 日付を入力して実行すると止まってしまい、どこがおかしいのかわかりません。
  • 初心者のため、皆さんのアドバイスをいただけると助かります。
回答を見る
  • ベストアンサー

昨日も質問させていただいた者です、何度もすみません

昨日も質問させていただいた者です、何度もすみません 万年カレンダーのプログラム(C言語)がわからなくて困っています 日付を入力するとその日付の曜日が出力されるプログラムです。 皆さんの回答を参考にしていろいろ直してみたんですが 日付を入力して実行するとエラーになり止まってしまいます どこがおかしいんでしょうか思いっきり初心者でごめんなさい #include <stdio.h> int main(void) { int d[13]={0, 31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 }; char youbi[7][4]={"日","月","火","水","木","金","土"}; int y ,m ,n ,a ,b ,c ,cc ,s=0 ,ss=0 ,e=0; printf("西暦="); scanf("%d",&y); printf("月="); scanf("%d",&m); printf("日="); scanf("%d",&n); for(a = 1900 ; a < y ; a++){ if(a%4 == 0 && (a%100 != 0 || a%400 == 0)){ s=s+2; }else{ s=s+1; } } if(y%4 == 0 && (y%100 != 0 || y%400 == 0)){ ss = 2; }else{ ss = 1; } if(ss == 2){ d[2] = 29; } else{ d[2] = 28; } for(b = 0 ; b <= m-1 ; b++){ e = d[b]+e; m += 1; } e = e+n; c = e%7; s = c+s; cc = s%7; printf("%c",youbi[cc]); ←調べてみたけど出力の仕方がいまいちわかんないです・・・ return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • wild_kit
  • ベストアンサー率32% (581/1804)
回答No.3

#include <stdio.h> int main(void) { int mdata[12]={ 31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 }; /*一月の日数*/ char youbi[7][4]={"日","月","火","水","木","金","土"}; /*曜日*/ int year ,month ,date ,a ,b ,ichi ,uruu=0 ,days=0; printf("西暦="); scanf("%d",&year); /*西暦入力*/ printf("月="); scanf("%d",&month); /*月名入力*/ printf("日="); scanf("%d",&date); /*日付入力*/ for(a = 1900 ; a < year ; a++) /*西暦1990年からスタート*/ {                             /*入力された年になったら抜ける*/  if(a%4 == 0 && (a%100 != 0 || a%400 == 0))  {                /*うるう年の際は通常より*/   uruu=uruu+1;                     /*1日増える*/   } } if(y%4 == 0 && (y%100 != 0 || y%400 == 0))       /*入力された年がうるう年か調べる*/ {  mdata[1] = 29;     /*うるう年なら2月は29日にする*/ } for(b = 0 ; b < month-1 ; b++)           /*入力された月よりも前の各月の*/ {                         /*日数を足しこんでいく。*/  days = mdate[b]+days; } days = days+date;                  /*入力された年内の日数*/ zure = (year-1900)+uruu+days; /*365=7*52+1なので1年でひとつずれる*/ ichi = zure%7; /*曜日の位置を求める*/ printf("%s",youbi[ichi]);           /*多分文字列指定にしないと駄目ですよね*/ return 0; }  20年ぶりに考えてみました。 ですから正しいとは限りません。 変数名を出来るだけ分かりやすいものに変えたつもりです。 西暦入力のデータ型を変える(10万年対応(^_^;))とか、不正入力チェックも入れたいですね。 基点(1990年1月1日)からの総日数(alldays)を出しても面白いと思います。 alldays = (year-1900)*365 + uruu + days

その他の回答 (5)

noname#144013
noname#144013
回答No.6

こんにちは。 プログラミングにおいて問題が発生した場合は、   どこまで上手く動作しているのか、   どこで上手くいかなくなったのか、 を見極める作業が必要だと思います。 そのためには、#2さんが言われているように、プログラムの要所要所にprintfなど を用いて、その実行時点の実際の変数等の中身がどうなっているのか(意図した 値なのか、そうでないのか)を確認した方が良いと思います。 また、デバッガが使用できる環境であれば、デバッガを用いて、プログラムを ステップ実行しながら変数の中身を確認するのも良いと思います。 ご提示のソースで、実行時にエラーになるのは、2つ目のforループ内の処理に 問題がある為だと思われます。   1)なぜ、m+=1 しているのか不明?     ・これは必要ないと思われます。   2)1)のため、ループ終了条件が成立しなくなり、ループが終了しない。   3)2)のため、配列 d[] のアクセス用のインデックス値 b が要素数の上限を    オーバーしてしまい、不正エリアにアクセスしてしまう。   4)3)のため、実行時エラーが発生していると思われます。 forループ内に、printf等で参照している変数の値を表示するようにしてみれば、 その状態がわかると思います。 ※この他にも、他の回答者の方が言われているように、幾つか問題点がある  ようです。 参考までに(参考になるかどうかわかりませんが)、ご提示のソースの原型を できるだけ保ちつつ修正を加えたソースを作成してみました。 宜しければ試してみて下さい。(※下記リンク先参照) ※下記ソース内にコメントとして、問題点、修正点などを記述してあります。 ■修正版ソース http://ideone.com/RfcQK 以上です。

takeda94
質問者

お礼

わかりやすい説明から修正ソースまで 親切にありがとうございました!!無事にプログラムを完成する事ができました

  • wild_kit
  • ベストアンサー率32% (581/1804)
回答No.5

 訂正 変数zureが宣言されていないので、追加してください。 コメント「1990年からスタート」は「1900年からスタート」 days = mdate[b]+days; は、 days = mdata[b]+days; 尚、youbi[ichi][0]はyoubi[ichi]と省略できます。 論理演算部分は正しいのではないかと思いますが、実際に動かして確認出来る環境にはありません。 1900年なら1900%4 == 0<T>,1900%100 != 0<F>,1900%400 ==0<F> T && (F||F)ですから、T && FでFでしょう。(=平年) 2000年なら、2000%4 == 0<T>,2000%100 != 0<F>,2000%400 == 0<T> T && (F||T)ですから、T && Tとなり、Tでしょう。(うるう年) あるいは、2004年なら2004%4 == 0<T>,2004%100 != 0<T>,2004%400 == 0<F> T && (T||F)ですから、T && Tとなり、Tでしょう。(うるう年) <T=真、F=偽> もしかすると演算の優先順位がからんで期待通りにならないのかもしれませんね。 その時は括弧でくくってください。

takeda94
質問者

お礼

本当にありがとう!!すごい参考になりました!!

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.4

みんな、そろそろ閏年の判定をちゃんとしたらどうかな。 西暦が4で割り切れて100では割り切れない、もしくは400で割り切れるのが閏年。 だから、1900年は平年で2000年は閏年。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

前と変わってないんだけどなぁ for(b = 0 ; b <= m-1 ; b++){ printf("開始時: b=%d,e=%d,m=%d\n",b,e,m); e = d[b]+e; printf("e=..後: b=%d,e=%d,m=%d\n",b,e,m); m += 1; printf("m+=1後: b=%d,e=%d,m=%d\n",b,e,m); printf("次は..: b=%d, ループ条件 <= m-1(%d)\n",b + 1, m-1); } printf("for終了:b=%d,e=%d,m=%d\n",b,e,m); printf("条件..: b=%d, ループ条件 <= %d (= m-1)\n",b, m-1); これで実行してみてください。ループの各所で各変数がどんな値になっているかが表示されます。 おそらく、その結果はあなたの意図していないものになっているはずです。 一度、各コマンドが何をやっているかの説明を日本語(あなたが他の言語の方がわかりやすいなら英語でも中国語でもいいですが)で書いてみることをお勧めします。できるだけ具体的に。 例えば、m+=1 なら 「mに1加える」ではなく「求める月mを次の月にする」といった具合に。 > printf("%c",youbi[cc]); ←調べてみたけど出力の仕方がいまいちわかんないです・・・ 本当に基本ですから、確実に憶えてください。 「%c」はマニュアルにはなんと書いてありました?例えば下のマニュアルには http://www.linux.or.jp/JM/html/LDP_man-pages/man3/printf.3.html > c (略)int 引き数を unsigned char に変換して、その結果に対応する文字を出力する(略) char youbi[7][4] ; と宣言してあります。 では、youbi[cc]の型は何だかわかりますか? 「文字」と「文字列」の違いは把握していますか?

  • DarkMoon
  • ベストアンサー率21% (225/1046)
回答No.1

5行目で char youbi[7][4]={"日","月","火","水","木","金","土"}; と宣言しているので printf("%c",youbi[cc]); では変数に入っている値を呼び出せません。 youbi[ ][ ] というように二つのカギ括弧に数値を入れて指定します。

関連するQ&A

  • 万年カレンダーのプログラム(C言語)が分からなくて困っています。

    万年カレンダーのプログラム(C言語)が分からなくて困っています。 一応作ってみたけどダメだったので何処がおかしいか指摘してくれると幸いです あとC言語についてはかなり初心者ですすみません #include <stdio.h> int main(void) { int d[13]={ 31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 }; char youbi[7][4]={"日","月","火","水","木","金","土"}; int y ,m ,n ,a ,b ,c ,cc ,s ,ss ,e; printf("西暦 月 日を入力"); scanf("%d ""%d ""%d ",y,m,n); for(a = 1900 ; a < y ; a++){ if(a % 4 == 0){ if(a % 400 == 0){ s = s+2; } else{ s = s+1; } } if(a % 100 == 0){ s = s+1; } else{ s = s+2; } } if(y % 4 == 0){ if(y % 400 == 0){ ss = ss+2; } else{ ss = ss+1; } } if(y % 100 == 0){ ss = ss+1; } else{ ss = ss+2; } if(ss == 2){ d[1] = 29; } else{ d[1] = 28; } for(b = 0 ; b < m+2 ; b++){ e = d[m] + e; m = m+1; } e = e+n; c = e%7; s = c+s; cc = s%7; printf("%c",youbi[cc]); return 0; }

  • 万年カレンダー

    万年カレンダーの日にちが、一日ずれて表示されますのでその原因を教えてください。 void main() { int nen,tuki,niti; int ff,i,n; int carender[6][7]; niti=0; for(i=0;i<6;i++)for(n=0;n<7;n++) carender[i][n]=0; printf("西暦(4桁)→"); scanf("%d",&nen); printf("month:"); scanf("%d",&tuki); ff=youbi_chk(nen,tuki,1); for(i=ff;i<7;i++) {carender[0][i]=niti;++niti;} for(n=1;n<6;n++){ for(i=0;i<7;i++){ if(niti<=niti_chk(tuki,nen)) {carender[n][i]=niti;++niti;}} } printf(" SUN MON TUE WED THU FRI SAT\n"); for(n=0;n<6;n++){ for(i=0;i<7;i++) if(carender[n][i]==0)printf(" ");else printf("%4d",carender[n][i]); printf("\n");} } int youbi_chk(int y,int m,int d) { int youbi; if(m<3) {y--; m+=10;} else {m-=2;} youbi=(y+(y/4)-(y/100)+(y/400)+(13*m-1)/5+d)%7; return youbi; } int uru_chk(int y) { if(y%400==0) return 1; if(y%100==0) return 0; if(y%4==0) return 1; return 0; } int niti_chk(int m,int y) { int hi[12]={31,28,31,30,31,30,31,31,30,31,30,31}; hi[1]+=uru_chk(y); return hi[m-1]; } プロトタイプ宣言は、省いてます。

  • C言語の質問です。

    #include"stdio.h" int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = a+b; printf("add=%d\n", add); return 0; } と、------------------------------------------------------------------------------ #include"stdio.h" int tasizan(int x, int y); int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = tasizan(a, b); printf("add=%d\n", add); return 0; } int tasizan(int x, int y){ int aa; aa = x + y; return aa; } の違いを教えてください。

  • どこが悪いのか・・・

    初めまして、こんばんわ。 学校の課題で、二次方程式のXの解を求めるC言語のプログラムを作ったのですが 何故か巧く起動しません。 よくわかりません・・・。 是非、何処が悪いのか指摘していただくと嬉しいです。 /*2-10(su210.c)*/ #include <stdio.h> #include <math.h> main() { int a,b,c; float D,x,y; printf("a*x^2+b*x+c=0のときa.b.cを入力して下さい。\n"); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); if(a=0){ if(b=c=0) printf("xはすべての実数をとる。"); else{ if(c=0&&b!=0) printf("x=0"); else{ if(b=0&&c!=0) printf("解なし。"); else{ if(b!=0&&c!=0) {x=-c/b; printf("x=%f",x);} } } } } else{ if(a!=0){ D=b^2-4*a*c; if(D>0){ x=(-b+sqrt(D))/2/a; y=(-b-sqrt(D))/2/a; printf("判別式はD>0です。\n"); printf("x1=%f\n",x); printf("x2=%f\n",y);} else{ if(D=0){x=-b/2*a;printf("判別式はD=0です。\n");printf("x=%f",x);} else{ if(D<0){printf("判別式はD<0です。\n");printf("解なし。");} } } } } }

  • 参照による呼び出し

    参照による呼び出しで3つの整数を大きい順に並び替えるという プログラムで、 #include<stdio.h> void change(int *x,int *y,int *z);/       main(){ int a,b,c; scanf("%d %d %d",&a,&b,&c); printf("入力データ:a=%d,b=%d,c=%d\n",a,b,c); change(&a,&b,&c); printf("入れ替え後:a=%d,b=%d,c=%d\n",a,b,c); return(0); } void change(int *x,int *y,int *z){ if(*x>*y){ *a=*x; *c=*y; } else{ *a=*y; *c=*x; } if(*z>*a){ *b=*a; *a=*z; } else if(*z>*c){ *b=*z; } else{ *b=*c; *c=*z; } } のように作ったのですが、zの値が一度も使われていないとエラーが 出てしまいます。どこをどう直せばいいか教えてください。 お願いします。

  • main関数以外での結果の表示?

    C言語で関数を用いたプログラムを作成しています。内容はA君、B君のボーリングの成績を入力し、その点数をランク付けするというものです。(250以上はS、200以上はA、150以上はB、100以上はC、50以上はD、50未満はFになります。) それから、このプログラムの条件は 1、main関数は値の入力と関数を呼び出すだけ。 2、関数の引数は入力した2つの値。 3、関数の中で結果を表示。 4、関数の戻り値はなし。 というもので、3番の結果のmain関数以外での結果の表示の仕方がわからず、どうやって結果を表示させていくのかよくわからず、行き詰っています。そのあたりの解説をしていただくとありがたいです。 なお、私が途中まで書いたので、問題点の指摘をおねがいいたします。 #include<stdio.h> int ia(int x); int ib(int y); int main(){  int a,b;  printf("A君のスコア");  scanf("%d",&a);  printf("B君のスコア");  scanf("%d",&b);  }  int ia(int x);  char ix;  if(x>=250){  ix = 'S';  }else if(x>=200 && x<250){  ix = 'A';  }else if(x>=150 && x<200){  ix = 'B';  }else if(x>=100 && x<150){  ix = 'C';  }else if(x>=50 && x<100){  ix = 'D';  else{  ix='F'; } int ib(int y);  char iy;  if(y>=250){  iy = 'S';  }else if(y>=200 && y<250){  iy = 'A';   }else if(y>=150 && y<200){  ix = 'B';  }else if(y>=100 && y<150){  iy = 'C';  }else if(y>=50 && y<100){  iy = 'D';  }else{  iy ='F'; }

  • 中央値をもとめる

    このプログラムだとたとえば 1、100、99を入力したときに間違った値を出します。どうすればいいでしょうか?おねがいします。 #include <stdio.h> int main(void) { int a, b, c, m; int max; printf("1個目の数値:"); scanf("%d", &a); printf("2個目の数値:"); scanf("%d", &b); printf("3個目の数値:"); scanf("%d", &c); max = a; if(max < b) max = b; if(max <= c) m = max; printf("%d, %d, %d の中央値は%dです。\n", a, b, c, m); }

  • 詳しい方に質問です

    Cを始めて2日目の初心者です。 #include <stdio.h> int main () { int a,b; printf("一つ目の数字を入力"); scanf("%d", &a); printf("二つ目の数字を入力"); scanf("%d" &b); printf("%d - %d = %d\n"a,b,a-b); } このプログラムの間違っているところを教えてください。

  • 3つの入力した数値の大小比較ができません。

    #include<stdio.h> int main() { int a,b,c; scanf("%d",&a); scanf("%d",&b); scanf("%d",&c); if(a<b) { if(b<c) { if(a<c) { printf("%d<%d<%d\n",a,b,c); } else { printf("%d%d%d",a,b,c); } } if(b>c) { if(a>c) { printf("%d<%d<%d\n",c,b,a); } else { printf("%d<%d<%d\n",a,c,b); } } } else if(a>b) { if(b>c) { if(a>c) { printf("%d>%d>%d\n",a,b,c); } else { printf("%d>%d>%d\n",a,c,b); } } else if(b>c) { if(a>b) { printf("%d>%d>%d\n",a,b,c); } else { printf("%d>%d>%d\n",b,a,c); } } else if(c>b) { if(c>a) { printf("%d<%d<%d\n",b,a,c); } else { printf("%d>%d>%d\n",a,c,b); } } else if(a<c) { if(a<b) { printf("%d<%d<%d\n",a,b,c); } else { printf("%d<%d<%d\n",b,a,c); } } else if(a>c) { if(a<b) { printf("%d>%d>%d\n",b,a,c); } else { printf("%d>%d>%d\n",a,b,c); } } else { printf("%d=%d=%d\n",a,b,c); } } 間違っている部分を教えてください。

  • 長方形、円、三角形の計算するプログラムでエラーがでます

    タイトルの通りなんですがエラーがでます>< コンパイラはできたのですが、実行して二つ目の入力するとこで、入力したあと止まります。 どこがおかしいのでしょうか? #include <stdio.h> int sikaku(void); int en(void); int main(void) { char ch; int a,b; printf("円(A) 長方形(B) 三角形(C)\n"); printf("入力してください:"); ch = getche(); if(ch == 'C'){ printf("\n底辺を入力してください:"); scanf("%d ",a); printf("高さを入力してください:\n"); scanf("%d",b); printf("%dです",a * b); } else if(ch == 'B') sikaku(); else if(ch == 'A') en(); return 0; } int en(void) { int a; float f; printf("\n半径を入力してください:"); scanf("%d",a); printf("円周率を入力してください:"); scanf("%f",f); printf("%fです",a * a * f); return 0; } int sikaku(void) { int a,b; printf("\n縦を入力してください:"); scanf("%d",a); printf("横を入力してくさい:\n"); scanf("%d",b); printf("dです",a * b); return 0; }

専門家に質問してみよう