• 締切済み

C++で日付のプログラミング

前回も同じ質問をして、自分なりに直してみたのですが、どうもうまく動作しません。 長くなりますが、教えてください。 日付のエラー処理を完全にするというもので、 次のような仕様を満たすようにMyDateクラスを修正せよ。というものです。 1.月、日共に初期値は1とする。 2.月、日の状態を出力するメンバ関数print()を追加する。 3.changeDay関数において、monthに入っている値に対応して適切なエラー処理を行う。    4月の時は日は30まで、5月の時は31まで、みたいな感じです。 4.changeMonth関数において、変更しようとする月に対しdayに入っている値が大きすぎる場合、dayを変更後の最後の日に修正するようにする。例えば、5月31日に設定されている時に、changeMonth(2)が呼ばれた時、monthに2を、dayに28を代入する。 5.うるう年は考慮しなくていい。 #include <stdio.h> class MyDate{ private: int month, day; public: void Date(int, int); void changeMonth(int); //「月」変更用関数 void changeDay(int); //「日」変更用関数 void print(); }; void MyDate::Date(int argMonth,int argDay) { argMonth = 1; argDay = 1; } void MyDate::changeMonth(int argMonth)//メンバ関数(changeMonth)の定義 { if(argMonth >= 1 && argMonth <= 12){ //1~12のときだけ値を更新 month = argMonth; } } void MyDate::changeDay(int argDay)//メンバ関数(changeDay)の定義 { //1~31が入力された場合のみ値を更新 if(argDay >= 1 && argDay <= 31){ day = argDay; } if(month == 1,day > 31){ printf("DATE = %d/%d\n",1,31); }else if(month == 2,day > 28){ printf("DATE = %d/%d\n",2,28); }else if(month == 3,day > 31){ printf("DATE = %d/%d\n",3,31); }else if(month == 4,day > 30){ printf("DATE = %d/%d\n",4,30); }else if(month == 5,day > 31){ printf("DATE = %d/%d\n",5,31); }else if(month == 6,day > 30){ printf("DATE = %d/%d\n",6,30); }else if(month == 7,day > 31){ printf("DATE = %d/%d\n",7,31); }else if(month == 8,day > 31){ printf("DATE = %d/%d\n",8,31); }else if(month == 9,day > 30){ printf("DATE = %d/%d\n",9,30); }else if(month == 10,day > 31){ printf("DATE = %d/%d\n",10,31); }else if(month == 11,day > 30){ printf("DATE = %d/%d\n",11,30); }else if(month == 12,day > 31){ printf("DATE = %d/%d\n",12,31); }else{ printf("DATE = %d/%d\n",month,day); } } int main(int, char **){ MyDate today; today.changeMonth(12); today.changeDay(35); return 0; } それで、 初期化するコンストラクタなんですが、 void MyDate::Date~ のような感じでいいのでしょうか? argMonthとかargDayとかいらないですか?ただMonthとDayだけでいいでしょうか? print()のメンバ関数なんですが、条件式の中に組込むとメンバ関数がいらないんじゃないか、と思ってしまうのですが、条件式の最後のelse{~}の中身を入れればいいでしょうか? あと、today.changeMonth(12); today.changeDay(35); と入れると、12/-858993460とでてしまうのですが、 条件式が間違ってるんでしょうか? 質問が多くてすみません。 よろしければ、回答よろしくお願いします。

みんなの回答

回答No.5

> メンバ関数の中でメンバ関数を呼ぶにはどうしたらいいのでしょうか? > そのまま、changeDay(int argDay)を書いてもいいのでしょうか? 訊くまでもない。やってみりゃイッパツでわかる。

回答No.4

ダメダメです。 1. changeDay内でprintfするのに何の意味もない。 そこでやらにゃならんのはDayの調整。 2. changeMonth内でchangeDayを呼ばないと狂う。 # 5/31にchangeMonth(2)すると2/31になっちまう

CHAMPloock
質問者

補足

回答ありがとうございます。 メンバ関数の中でメンバ関数を呼ぶにはどうしたらいいのでしょうか? そのまま、changeDay(int argDay)を書いてもいいのでしょうか?

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

C++のコンストラクは ・クラス名と同じ名前 ・戻り値およびその型は「指定しない」。voidではありません です。 なので、プロトタイプは class MyDate { MyDate(); } です。 省略すれば、デフォルトのコンストラクタが用意されます。 コンストラクタの定義の中で明示的に呼び出さない限り、他のメソッドが使われるとはありません。 > void MyDate::Date(int argMonth,int argDay) > { > argMonth = 1; > argDay = 1; >} 仮引数 argMonth,argDayを通常のローカル変数として利用し、1を代入するだけのメソッドになっています。つまり「何もしない」と同じです。 > print()のメンバ関数なんですが、条件式の中に組込むとメンバ関数がいらないんじゃないか、と思ってしまうのですが、条件式の最後のelse{~}の中身を入れればいいでしょうか? 質問文から読みとれる仕様には 「changeDayで日付を表示する」 なんてものは含まれていません。現状で表示しているのは正しいのでしょうか? メンバ変数を(エラーチェックしつつ)設定するだけの仕様ではないですか? > //1~31が入力された場合のみ値を更新 > if(argDay >= 1 && argDay <= 31){ > day = argDay; >} 現状、 month=2の時でも changeDay(31)とすると、このifの条件は真になり、dayに31が設定されます。 これは条件3に違反しています。 その下のif文でひっかかりますが(カンマを修正したとして)、ただ表示するだけで、値は修正されません。 それから、条件4が実装されていません。 > if(month == 1,day > 31){ > printf("DATE = %d/%d\n",1,31); カンマが間違いなのは既出なのでおいとくとして。 自分で書いてて嫌にならなかったですか? changMonthに条件4を実装しようとすると、もう一回、ほぼ同じものをかかなければなりません。 こういうのは、同じ書き方でできる仕組みを考えるとずーっと楽になります。 例えば int lastDay(int month) メソッドとして、month月の最終日を返すものを用意すれば、このifの羅列が if ( day > lastDay(month) ) { エラー処理 } だけ済みます。また、changeMonthへの条件4の追加も、このメソッドで簡単にできます。

CHAMPloock
質問者

補足

わかりやすい回答ありがとうございます。 自分でも面倒だな、とは思ってたんですが、他の方法が思いつかなくって…^_^; それで、 int lastDay(int month) メソッドを参考にしたいのですが、 lastDayというのは、配列を使ったらいいでしょうか?

  • TT414
  • ベストアンサー率18% (72/384)
回答No.2

>if(month == 1,day > 31){ >printf("DATE = %d/%d\n",1,31); >}else if(month == 2,day > 28){ >printf("DATE = %d/%d\n",2,28); >}else if(month == 3,day > 31){ >printf("DATE = %d/%d\n",3,31); とありますが一行一文にこだわらずに if(month == 1,day > 31){printf("DATE = %d/%d\n",1,31);} else if(month == 2,day > 28){printf("DATE = %d/%d\n",2,28);} else if(month == 3,day > 31){printf("DATE = %d/%d\n",3,31);} としたほうが見やすい、分かりやすいと思いますがどうでしょう?

CHAMPloock
質問者

お礼

確かにこれなら中かっことかわかりやすいですね ありがとうございます(^u^)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>初期化するコンストラクタなんですが、 >void MyDate::Date~ >のような感じでいいのでしょうか? クラス名と同じ…なので、 void MyDate::MyDate() かと。 引数などには注意が必要でしょうけど。 >argMonthとかargDayとかいらないですか?ただMonthとDayだけでいいでしょうか? 引数で受け取ったモノを「メンバ変数」に代入するなりしないと意味がないと思いませんか? # 受け取った変数の内容だけ書き換えても無意味です。 あと、引数で受け取った内容が正しいものかどうかの確認も必要…でしょう。 # 初期化リストとかいろいろ手法がありますが…そちらはC++に詳しい方の回答に期待しておきます。 >print()のメンバ関数なんですが、条件式の中に組込むとメンバ関数がいらないんじゃないか、と思ってしまうのですが、条件式の最後のelse{~}の中身を入れればいいでしょうか? print()メンバ関数は、「表示するだけ」でいいのではないですか? changeMonth()/changeDay()メンバ関数で、渡された日付などが正しいか判定してメンバ変数に設定すればよいでしょう。 ……まぁ、無条件に受け入れてprint()メンバ関数で処理してもかまいませんけど。 # getMonth()/getDay()/getDate()とか追加した時に変な日付が渡されるけどそういうクラス設計であればいいだけのことですし。 >if(month == 1,day > 31){ if(month == 1 && day > 31) { と書きたいのではないですか? 「複数の条件」の書き方が想定とは違いますが…… >あと、today.changeMonth(12); >today.changeDay(35); >と入れると、12/-858993460とでてしまうのですが、 >条件式が間違ってるんでしょうか? 希望している >}else if(month == 12,day > 31){ に引っかからなかったのでしょう。 dayの値は不明ですしね。 コンストラクタで初期化していないからゴミが入っています。 今回は負数だったのでdayは31より小さかったのでしょう。

関連するQ&A

  • C++で、日付をプログラミング

    C++勉強中です。課題が出たので質問したいです。よろしくお願いします。 日付のエラー処理を完全にするというもので、 次のような仕様を満たすようにMyDateクラスを修正せよ。というものです。 1.月、日共に初期値は1とする。 2.月、日の状態を出力するメンバ関数print()を追加する。 3.changeDay関数において、monthに入っている値に対応して適切なエラー処理を行う。    4月の時は日は30まで、5月の時は31まで、みたいな感じです。 4.changeMonth関数において、変更しようとする月に対しdayに入っている値が大きすぎる場合、dayを変更後の最後の日に修正するようにする。例えば、5月31日に設定されている時に、changeMonth(2)が呼ばれた時、monthに2を、dayに28を代入する。 5.うるう年は考慮しなくていい。 #include <stdio.h> class MyDate{ private: int day, month; public: MyDate(int =1, int = 1); void changeMonth(int); //「月」変更用関数 void changeDay(int); //「日」変更用関数 void print(); }; void MyDate::changeMonth(int argMonth)//メンバ関数(changeMonth)の定義 { if(argMonth >= 1 && argMonth <= 12){ //1~12のときだけ値を更新 month = argMonth; } } void MyDate::changeDay(int argDay)//メンバ関数(changeDay)の定義 { //1~31が入力された場合のみ値を更新 if(argDay >= 1 && argDay <= 31){ day = argDay; } } void MyDate::print() { if(month = 2 && day > 28){ printf("DATE = %d/%d\n",1,31); }else if(month = 4,6,9,11 && day > 30){ printf("DATE = %d/%d\n",month-1,31); }else{ printf("DATE = %d/%d\n",month,day); } } int main(int, char **){ MyDate today; today.changeDay(30); today.changeMonth(9); return 0; } 途中まで考えたのですが、煮詰まってしまってうまくいきません。 ifは使いますよね? void MyDate::print() の所はこれでいいのでしょうか? よろしくお願いします。

  • C言語

    #include <stdio.h> int main(void) { int month, days; puts("月を入力してください:"); scanf("%d",&month); // if(month == 2) days = 28; if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12); days = 31; else days=30; printf("%d月は%d日あります。\n", month, days); return(0); } // 月と日数の場合わけをしたいのですがうまくいきません。どこをなおせばいいのか誰か教えてください!

  • C言語

    #include <stdio.h> int main(void) { int month, days; puts(\"月を入力してください:\"); scanf(\"%d\",&month); // if(month == 2) days = 28; if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12); days = 31; else days=30; printf(\"%d月は%d日あります。\\n\", month, days); return(0); } // 月と日数の場合わけをしたいのですがうまくいきません。どこをなおせばいいのか誰か教えてください!

  • C言語について

    #include <stdio.h> #include <string.h> #include <time.h> typedef struct { int day; double dist; char comment[32]; } diary; void writeData(char datafile[]); void viewData(char datafile[]); char datadir[] = "dat/"; int year, month, day; int main(int argc, char* argv[]) { char datafile[11]; struct tm *date; time_t now; now = time(NULL); date = localtime(&now); year = date->tm_year + 1900; month = date->tm_mon + 1; day = date->tm_mday; sprintf(datafile, "walk%04d%02d", year, month); if ((argc > 1) && (strcmp(argv[1], "-view")==0)) { viewData(datafile); } else { writeData(datafile); } return 0; } void writeData(char datafile[]) { diary today_data; FILE *outfp; //出力ファイルのファイルポインタ char y_n = 'n'; char filename[15]; char input_str[12]; printf("%d/%d/%dの記録をしますか? (y/n) > ", year , month, day); scanf("%c", &y_n); while (getchar() != '\n') { } if(y_n != 'y') { printf("記録する日付は?(例:%d %d %d) > ", year, month, day); year = 0; month = 0; day = 0; gets(input_str); sscanf(input_str, "%d %d %d", &year, &month, &day); if((year > 9999) || (month > 12) || (month < 1) || (day > 31) || (day < 1)) { printf("日付が正しくありません\n"); return; } sprintf(datafile, "walk%04d%02d.txt", year, month); } today_data.day = day; printf("距離は? > "); scanf("%lf", &today_data.dist); while (getchar() != '\n') { } printf("コメントは?(30文字以内) > "); fgets(today_data.comment, 32, stdin); if((strlen(today_data.comment) == 31) && (today_data.comment[30] != '\n')) { while (getchar() != '\n') { } } sprintf(filename, "%s%s", datadir, datafile); if((outfp = fopen(filename, "a+")) == NULL) { printf("ファイルオープンエラー\n"); return; } fprintf(outfp, "%d %.2lf ", today_data.day, today_data.dist); if((strlen(today_data.comment) == 31) && (today_data.comment[30] != '\n')) { today_data.comment[30] = '\n'; today_data.comment[31] = '\0'; } fprintf(outfp, "%s", today_data.comment); fclose(outfp); printf("記録しました"); } void viewData(char datafile[]){ } このソースの char datadir[] = "dat/";この宣言はディレクトリを指しているんですよね? この場合の/はどおいう意味ですか? 教えてください

  • C言語で分からないところがあるのですが……

    C言語で分からないところがあるのですが…… すみません。C言語を学習していてつまづいたので、皆さんの意見を聞きたいと思います。 現在、カレンダーを表示するプログラムをつくっています。 Yearとmonthをユーザが入力すると、その年その月のカレンダーが出るという算段です。(画像貼っておきます。ソースコードは下) これはできました。 これをいじって、Yearをユーザから受け取ると、その年の1月から12月までのカレンダーがば~っと表示されるようにしろ、と言われました。 Yearとmonthを受け取って書くやつは友人の助けを得ながらなんとかかけましたが、もう無理です。多分、for文を使うんだと思うんですが……助けてください! #include <stdio.h> int dayofweek(int year, int month); int daysinmonth(int year, int month); int daysinyear(int year); void showcal(int dow, int days); int main(void) { int year, month; int dow; int dim; printf ("Year?: "); scanf ("%d", &year); printf ("Month?: "); scanf ("%d", &month); dow = dayofweek(year, month); dim = daysinmonth(year, month); showcal(dow, dim); return 0; } void showcal (int dow, int days) { int i, j, d; printf ("Su Mo Tu We Th Fr Sa\n"); d = 1; for (i = 0; i < dow; i++) { printf (" "); } for (; i < 7; i++) { printf (" %d ", d); d++; } printf("\n"); for (j = 0; d <= days; j++) { for (i = 0; i < 7 && d <= days; i++) { if (d < 10) printf (" %d ", d); else printf ("%d ", d); d++; } printf("\n"); } } int daysinmonth( int year, int month) { int dim; dim = 31; if (month == 4 || month == 6 || month == 9 || month == 11) dim = 30; if (month == 2) { if ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) dim = 29; else dim = 28; } return dim; } int daysinyear( int year) { int diy; if ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) diy = 366; else diy = 365; return diy; } int dayofweek (int year, int month) { int dow; int days; int y, m; if (year >= 2000) { days = 0; for ( y = 2000; y < year; y++ ) { days = days + daysinyear(y); } for ( m = 1; m < month; m++ ) { days = days + daysinmonth(year, m); } dow = (6 + days) % 7; } else { days = 0; for ( m = month; m <= 12; m++ ) { days = days + daysinmo

  • C言語の穴埋め問題なのですが

    ???の中身を教えてください #include <stdio.h> #define N 3 //構造体の宣言 typedef struct date{ char *nengou; int year; int month; int day; }DATE; //関数のプロトタイプ宣言 void disp(DATE data); int main(void) { DATE birthday; char buff[80]; ???= buff; printf("年号:"); scanf("%s" , birthday.nengou); printf("年:"); scanf("%d" ,&birthday.year ); printf("月:"); scanf("%d" , &birthday.month); printf("日:"); scanf("%d" ,&birthday.day ); disp(birthday ); } void disp(DATE data) { printf("%s%d年%d月%d日\n" , data.nengou , data.year , data.month , data.day); }

  • C言語 実行エラー 10000日先が表示されない 

    今10000日先後の年、月、日を求めていて下のプログラムを 考えたんですけど、コンパイルは通るんですが結果がうまくいきません↓ どこがおかしいですか? #include<stdio.h> int leapYear(int); int Date(int,int,int,int); int main(void){ int year,i=0,month,date,date2=10000,emp=0; printf("年>>"); scanf("%d",&year); printf("月>>"); scanf("%d",&month); printf("日>>"); scanf("%d",&date); Date(year,month,date,date2);//date2から各月の日数を引いていく printf("year=%d month=%d date=%d date2=%d \n",year,month,date,date2); return 0; } int leapYear(int year){ //うるう年を求める if(year%400==0){ return 1; } else if(year%4==0 && year%100!=0){ return 1; } else return 0; } int Date(int y,int m,int d,int d2){ for(;;y++){ if(d2<0) return y,m,d,d2; for(;m<=12 || d2>=0;m++){ if(leapYear(y)==1){ if(m==4||m==6||m==9||m==11){ d2-(30-d); } else if(m==2) d2-(29-d); else d2-(31-d); } else if(m==4||m==6||m==9||m==11){ d2-(30-d); } else if(m==2) d2-(28-d); else d2-(31-d); } } }

  • 万年カレンダで祝日にマークを付けるには

    祝日に関して、下記の通りプログラムを作ったのですがうまくいきません。ご教授お願いします。 void Display_func( int year , int month ) {   int week , i , leap , day , *shuku , *furikae ;   int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};   int d = 0; **省略**   for( i=0 ; i<week ; i++ ){      printf(" ");   }   for(day=1 ; day<=days[month] ; day++ ){ ★★Yasumi_func( int &shuku , int &furikae ); /*祝日判定関数*/   if(i==0){     printf(" @%2d",day);   }else if(i==*shuku){      printf(" #%2d",day);   }else if(i==*furikae){     i = 1;     printf(" &%2d",day+1);   }else if(i==6){     printf(" *%2d",day);   }else{     printf(" %2d",day);   } 略 @:日曜日 *:土曜日 &:振替休日 #:祝日 return; } /* 祝日判定関数 */ void Yasumi_func( int *yshuku , int *furikae ) { int year , month , day , i ; if((month==3 && day== (int)(20.8431 + 0.242194*(year-1980) - (year-1980)/4))   || (month==1 && day>7 && day<15 && i==1) 略   || (month==11 && day==3)   || (month==12 && day==23))   {     if(i == 0){       *furikae = i ;      /* 振替休日 */     }else{       *shuku = i; /* 祝日 */     }   } }   Yasumi_func( int &yasumi , int &kae ); 祝日判定関数を呼びたいのですが「式の構文エラー」となってしまいます。 この他   if(i == 0){     *furikae = i ;   }else{     *shuku = i;   } この部分も自信がないので、アドバイスお願いいたします

  • 本日の日付を”「」”で括りたい

    今はカレンダーにかんする課題をやっております。 本日の日付を”「」”で括りたいので方法がよくわかりません。 こんな感じ ーーーー9月ーーーー  月 火 水 木 金 土 日 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 ソースを上げますので教えてください。 public class Canlda { public static void main(String[] A00) { Calendar L00 = Calendar.getInstance(); int L01 = L00.get(YEAR); int L02 = L00.get(MONTH); int date= L00.get(DATE); L00.set(L01, L02, 1); int L03 = L00.getActualMaximum(DAY_OF_MONTH); int L04 = L00.get(DAY_OF_WEEK); System.out.printf("ーーーー%d月ーーーー %n",L02 + 1); System.out.println("月 火 水 木 金 土 日"); // 空白の個数を求める int L06; if (L04 < MONDAY) { L06 = (L04 + 7) - MONDAY; } else { L06 = L04 - MONDAY; } int L05 = 0; for (int L07 = 0; L07 < L06; L07++) { System.out.print(" "); L05++; } for (int L08 = 1; L08 <= L03; L08++) { if (L05 < 6) {          if(date == L08){ System.out.printf("[%2d] ", L08); } System.out.printf("%2d ", L08); } else { System.out.printf("%2d%n", L08); } L05 = ++L05 % 7; } } } よろしくお願いします。

  • このソースがコンパイルエラーになってしまいます

    このソースのどこがわるいのかわかりません エラー時にこのようなエラーメッセージが出ます In function `writedata': 52: error: syntax error before string constant 65: error: syntax error before string constant 89:2: warning: no newline at end of file ソースはこれです #include <stdio.h> #include <string.h> #include <time.h> typedef struct { int day; double dist; char comment[32]; } diary; void writedata(char datafile[]); void viewdata(char datafile[]); char datadir[] = "dat/"; int year,month,day; int main(int argc,char *argv[]) { char datafile[11]; struct tm *date; time_t now; now = time(NULL); date = localtime(&now); year = date->tm_year + 1900; month = date->tm_mon + 1; day = date->tm_mday; sprintf(datafile,"walk%04d%02d",year,month); if((argc > 1) && (strcmp(argv[1],"-view")==0)) { viewdata(datafile); } else { writedata(datafile); } return 0; } void writedata(char datafile[]) { diary today_data; FILE *outfp; char y_n = 'n'; char filename[15]; char input_str[12]; printf("%d/%d/%dの記録をしますか?(y/n) > ",year,month,day); scanf("%c", &y_n); while(getchar() != '\n') { } if(y_n != 'y') { printf("記録する日付は?(例:%d %d %d) > ",year,month,day); year = 0; month = 0; day = 0; gets(input_str); sscanf(input_str"%d %d %d",&year,&month,&day); if((year > 9999) || (month > 12) || (month < 1) || (day > 31)|| (day < 1)) { printf("日付が正しくありません\n"); return; } sprintf(datafile,"walk%04d%02d",year,month); } today_data.day = day; printf("距離は? >"); scanf("%lf", &today_data.dist); while(getchar() != '\n') { } printf"コメントは?(30文字以内) >"); fgets(today_data.comment, 32, stdin); if((strlen(today_data.comment) == 31) && (today_data.comment[30] != '\n')) { while (getchar() != '\n') { } } sprintf(filename, "%s%s",datadir,datafile); if((outfp = fopen(filename,"a+")) == NULL) { printf("ファイルオープンエラー\n"); return; } fprintf(outfp , "%d %.2lf", today_data.day,today_data.dist); if((strlen(today_data.comment) == 31) && (today_data.comment[30] != '\n')) { today_data.comment[30] = '\n'; today_data.comment[31] = '\0'; } fprintf(outfp,"%s",today_data.comment); fclose(outfp); printf("記録しました"); } void viewdata(char datafile[]) { } なぜ、エラーになったか教えてくださいお願いします

専門家に質問してみよう