• ベストアンサー

C言語の問題

自分の生まれた日から、今日までの生存日数を求めよ。(但し、うるう年なども計算するプログラム)という問題を提示されたのですが、ぜんぜんわかりません。どなたか上記プログラムがわかる方、ご教授お願いいたします。 #include<stdio.h> int main(void) { int table1[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int table2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; int mm,dd,i,day=0; /*(1)指定月日までの日数計算*/ do { printf("月>"); scanf("%d",&mm); if(mm>=1 && mm<=12)break; printf("月(%d)は誤りです。\n",mm); }while(1); do { printf("日>"); scanf("%d",&dd); if(dd>=1 && dd<=table1[mm])break; printf("日(%d)は誤りです。\n",dd); }while(1); for(i=1;i<mm;i++) day += table1[i]; day += dd; printf("1/1から%d/%d迄の日数は%d日です。\n",mm,dd,day); return 0; } ↑参考までにこんなプログラムでやっています。

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

  • ベストアンサー
  • essential
  • ベストアンサー率100% (1/1)
回答No.4

No.3 の人に近い?ですが、1970年1月1日以降に生まれた人なら 次のようなものでもOKですよ。 #include <stdio.h> #include <time.h> void main( void ) { int year = 0; int mon = 0; int day = 0; time_t timer; struct tm t; /* 現在時刻の取得 */ time(&timer); /* 自分の生年月日(年月日:19871231)を入力 */ scanf( "%4d%02d%02d" ,&year, &mon, &day ); memset( &t, 0, sizeof( struct tm ) ); t.tm_year = year - 1900; t.tm_mon = mon - 1; t.tm_mday = day; /* 構造体を秒に変換 */ if( ( timer = mktime( &t ) ) == -1 ) { printf( "生年月日が変です\n " ); exit( 0 ); } /* 現在時刻との差分をとる */ timer = time( 0 ) - timer; printf( "生存日数は %d 日です\n", timer / ( 24 * 60 * 60 ) ); }

svst
質問者

お礼

わざわざ、プログラム本体を掲載してもらい非常に参考になります。 ありがとうございました。 1つ、質問ですがこのプログラムは閏年を計算しているのでしょうか。 (ぱっと見るとちょっと分からないのですが、教えていただけると幸いです)

その他の回答 (5)

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.6

#4のプログラムについて > 1つ、質問ですがこのプログラムは閏年を > 計算しているのでしょうか。 計算するまでもなく、time関数はうるう年計算を内蔵しているから大丈夫です。 しかし、問題点は、time_tがsigned longの場合、1901年12月15日~2038年1月19日までしかうまく動かないという点です。 ということで、正しくは真っ向から計算するべきですね。

svst
質問者

お礼

time関数はうるう年計算を内蔵している事は知りませんでした。 勉強になりました。 アドバイス有難うございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

/* 基準日:西暦1年1月1日(月)を基準に日付の計算をする */ #include <stdio.h> #include <stdlib.h> #include <time.h> int isLeapYear(unsigned y){ return ((0 == y % 400)||((0 == y % 4)&&(0 != y % 100))); } unsigned leapDays(unsigned y){ /* 基準日から指定年までの閏日の日数 */ return (y/4 - y/100 + y/400); } unsigned daysFromYearTop(unsigned y, unsigned m, unsigned d){ /* 指定日の年頭からの日数 */ static unsigned daysOfMonth[]={ NULL, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; return (daysOfMonth[m]+((m>2 && isLeapYear(y))? 1:0) + d); } unsigned long days(unsigned y, unsigned m, unsigned d){ /* 基準日から指定日までの通算日数 */ unsigned lastYear=y-1; return(leapDays(lastYear) + lastYear*365 + daysFromYearTop(y, m, d)); } int main(void){ unsigned y, m, d; unsigned long todays, birthday; struct tm *today; time_t now; now=time(NULL); today=localtime(&now); y=today->tm_year + 1900; m=today->tm_mon + 1; d=today->tm_mday; todays=days(y,m,d); birthday=days(1945,8,15); /* 1945/8/15日生まれ */ printf("生存日数:%lu\n",todays-birthday);/* 生まれたその日は0 */ return(EXIT_SUCCESS); }

svst
質問者

お礼

わざわざ、プログラム本体を掲載してもらってありがとうございます。 今後の参考にさせて頂きます。

  • vivlet
  • ベストアンサー率36% (24/66)
回答No.3

問題点は先のお二人のお返事にありますから、別の視点で。 二つの日付間の日数を求めるには、ユリウス日や準ユリウス日に変換して算出すると楽ですよ。 ユリウス日とは、紀元前4713年1月1日からの連続した通し番号の日数で 準ユリウス日は、1858年11月17日0時(世界標準時)です。 プログラム方ですが 1.生年月日入力 2.現在日付取得 3.生年月日を準ユリウス日に変換 4.現在日付を準ユリウス日に変換 5. 4 と 3 の差を求める になりますね。 詳しい説明や変換方法は参考URLで

参考URL:
http://homepage1.nifty.com/manome/astrology/julian.html
svst
質問者

お礼

アドバイスをして頂き、有難うございました。 参考URLを教えていただき、非常に助かります。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.2

年のことが考えてありませんね。 生存日数ですから18歳なら6000日以上の日数になるはずです。 生まれた年の誕生日から今日までということです。

svst
質問者

お礼

アドバイスをして頂き、有難うございました。 確かに、年数が抜けていました。 再構築をしてみます。

  • trajaa
  • ベストアンサー率22% (2662/11921)
回答No.1

ぱっと見て ・年については何も処理が無い ・年が不明なので閏年の判定も無い ・1/1から指定日付までの日数は計算している ・指定日付が生年月日なら、指定日付から12/31迄の日数を求めなければならないのでは? ・今日という日付はどこにも無い という感じで、基本的な部分が不足・誤解しているようです。 まずは、日本語(フローチャートが書けるならそちら)で、何が必要な情報で、どういった手順で処理を実行していくのかを、書き出してみてください。 その後、その日本語をソースコードに置き換えていくイメージで。

svst
質問者

お礼

アドバイスを、有難うございます。 フローチャートを書いてから、再度トライしてみようと思います。