質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

Q&A

解決済

3回答

392閲覧

C言語でカレンダーソフトを作成しているが振替休日の判定で無限ループになってしまう

sonozaki_SZ

総合スコア28

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

0グッド

0クリップ

投稿2017/06/12 14:58

編集2017/06/18 16:41

OS: Windows 7 64bit
開発環境: Visual Studio 2017
ソリューション:空のプロジェクト
デバッガー: ローカル Windowsデバッガー x86

c言語

1**calendar.h** 2 3#ifndef CALENDAR_H 4#define CALENDAR_H 5 6#define STR_LEN 8 /* 文字列の長さ */ 7#define P_HOLIDAY 1 /* 祝日 */ 8#define O_HOLIDAY 2 /* 振替休日 */ 9#define N_HOLIDAY 3 /* 国民の休日 */ 10 11void read_year_month(int *y, int *m); /* 年と月の入力と入力値の判定後に適正値を引数に代入 */ 12void print_calendar(int *y, int *m); /* カレンダーの表示 */ 13 14#endif

C言語

1**main.c** 2 3#include <stdio.h> 4#include "calendar.h" 5 6int main(void) 7{ 8 int year; /* 年 */ 9 int month; /* 月 */ 10 11 puts("年、月を入力後にその月のカレンダーを表示します"); 12 read_year_month(&year, &month); /* 年と月の入力と入力値の判定後に適正値を引数に代入 */ 13 print_calendar(&year, &month); /* カレンダーの表示 */ 14}

C言語

1**read_year_month.c** 2 3#include <stdio.h> 4#include <stdbool.h> 5#include "calendar.h" 6 7void read_year_month(int *y, int *m) 8{ 9 char str[STR_LEN]; 10 int i; 11 bool err_flg; 12 13 fflush(stdin); /* 入力バッファのフラッシュ */ 14 15 puts("年を2016~2099の範囲、月を1~12の範囲で入力して下さい"); 16 puts("年と月の間を半角スペースで区切って下さい"); 17 puts("例:2016 1/2099 12"); 18 printf("年と月の入力:"); 19 fgets(str, sizeof(str), stdin); 20 fflush(stdin); 21 22 /* 数字,半角スペース,改行文字の値以外が入力された場合にエラーフラグを立てる */ 23 for (i = 0; i < STR_LEN - 1; i++) 24 { 25 if (('0' < str[i] && str[i] < '9') || (str[i] == ' ' || str[i] == '\n')) 26 { 27 err_flg = false; 28 } 29 else 30 { 31 err_flg = true; 32 } 33 } 34 sscanf_s(str, "%d %d", y, m); /* 文字型を整数型に変換して引数y, mに値を代入 */ 35 /* 範囲外の値が入力されたらエラーフラグを立てる */ 36 if ((*y < 2016 || 2099 < *y) || (*m < 1 || 12 < *m)) 37 { 38 err_flg = true; 39 } 40 else 41 { 42 err_flg = false; 43 } 44 45 /* エラー処理 */ 46 if (err_flg == true) 47 { 48 puts("入力された値は不正です"); 49 puts("入力し直して下さい"); 50 read_year_month(y, m); 51 } 52 else 53 { 54 /* NOP */ 55 } 56}

C言語

1**print_calendar.c** 2 3#include <stdio.h> 4#include "calendar.h" 5 6int c_lday(int y, int m); /* 末日を求める関数 */ 7int c_dow(int y, int m, int d); /* 任意の日付の曜日を求める関数 */ 8int d_holiday(int y, int m, int d, int w); /* 祝日、振替休日、国民の休日の判定をする関数 */ 9void print_holiday(int y, int m, int d, int w); /* 国民の祝日を表示する関数 */ 10void day_before(int *y, int *m, int *d, int *w);/* 前日を返す関数 */ 11void day_next(int *y, int *m, int *d, int *w); /* 翌日を返す関数 */ 12 13void print_calendar(int *y, int *m) 14{ 15 int day; /* 日にち */ 16 int dow; /* 曜日 */ 17 int const lday = c_lday(*y, *m); /* 末日 */ 18 const char p_dow[7][3] = { "日", "月", "火", "水", "木", "金", "土" }; /* 曜日表示用 */ 19 int hol_flg; /* 祝日、振替休日、国民の休日フラグ */ 20 21 ///* 初日の曜日を求める */ 22 //day = 1; 23 //dow = c_dow(*y, *m, day); 24 puts("****************************"); 25 printf(" %d年%d月のカレンダー\n", *y, *m); 26 puts("****************************"); 27 for (day = 1; day <= lday; day++) /* 初日から末日までループ */ 28 { 29 dow = c_dow(*y, *m, day); /* 当日の曜日を求める */ 30 hol_flg = d_holiday(*y, *m, day, dow); /* 祝日判定 */ 31 32 /* カレンダーの表示 */ 33 printf("%2d日 (%s) ", day, p_dow[dow]); 34 if (hol_flg == P_HOLIDAY) 35 { 36 print_holiday(*y, *m, day, dow); 37 } 38 else if (hol_flg == O_HOLIDAY) 39 { 40 puts("振替休日"); 41 } 42 else if (hol_flg == N_HOLIDAY) 43 { 44 puts("国民の休日"); 45 } 46 else 47 { 48 putchar('\n'); 49 } 50 /* 曜日を進める処理 後で追加 */ 51 } 52 getchar(); /* コンソールの終了待機処理 */ 53} 54 55int c_lday(int y, int m) 56{ 57 if (m == 2) /* 2月なら */ 58 { 59 /* うるう年の判定 */ 60 if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) /* 400で割り切れるか、4で割り切れるが100で割り切れない年だったら */ 61 { 62 return 29; 63 } 64 else 65 { 66 return 28; 67 } 68 } 69 else if (m == 4 || m == 6 || m == 9 || m == 11) /* 直前までの条件を除く4月、6月、9月、11月だったら */ 70 { 71 return 30; 72 } 73 else 74 { 75 return 31; 76 } 77} 78 79int c_dow(int y, int m, int d) 80{ 81 if (m == 1 || m == 2) 82 { 83 y--; 84 m += 12; 85 return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d) % 7; 86 } 87 else 88 { 89 return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d) % 7; 90 } 91} 92 93int d_holiday(int y, int m, int d, int w) 94{ 95 /* 引数で受け取った値をローカルにコピー */ 96 int buf_y, buf_y2; 97 int buf_m, buf_m2; 98 int buf_d, buf_d2; 99 int buf_w, buf_w2; 100 int flg; 101 buf_y = y; 102 buf_m = m; 103 buf_d = d; 104 buf_w = w; 105 106 /* 国民の祝日の判定 */ 107 if ((buf_m == 1 && buf_d == 1) /* 1/1 元日 */ 108 || (buf_m == 1 && buf_w == 1 && 8 <= buf_d && buf_d <= 14) /* 1月第2月曜 成人の日 */ 109 || (buf_m == 2 && buf_d == 11) /* 2/11 建国記念の日 */ 110 || (buf_m == 3 && buf_d == (int)(20.8431 + 0.242194 111 * (buf_y - 1980) - (buf_y - 1980) / 4)) /* 3/20付近 春分の日 */ 112 || (buf_m == 4 && buf_d == 29) /* 4/29 昭和の日 */ 113 || (buf_m == 5 && buf_d == 3) /* 5/3 憲法記念日 */ 114 || (buf_m == 5 && buf_d == 4) /* 5/4 みどりの日 */ 115 || (buf_m == 5 && buf_d == 5) /* 5/5 こどもの日 */ 116 || (buf_m == 7 && buf_w == 1 && 15 <= buf_d && buf_d <= 21) /* 7月第3月曜 海の日 */ 117 || (buf_m == 8 && buf_d == 11) /* 8/11 山の日 */ 118 || (buf_m == 9 && buf_w == 1 && 15 <= buf_d && buf_d <= 21) /* 9月第3月曜 敬老の日 */ 119 || (buf_m == 9 && buf_d == (int)(23.2488 + 0.242194 120 * (buf_y - 1980) - (buf_y - 1980) / 4)) /* 9/23付近 秋分の日 */ 121 || (buf_m == 10 && buf_w == 1 && 8 <= buf_d && buf_d <= 14) /* 10月第2月曜 体育の日 */ 122 || (buf_m == 11 && buf_d == 3) /* 11/3 文化の日 */ 123 || (buf_m == 11 && buf_d == 23) /* 11/23 勤労感謝の日 */ 124 || (buf_m == 12 && buf_d == 23)) /* 12/23 天皇誕生日 */ 125 { 126 flg = P_HOLIDAY; 127 } 128 else if (w != 0 || w != 6) /* 祝日か土日ではなかったら */ 129 { 130 /* 振替休日の判定 */ 131 do 132 { 133 day_before(&buf_y, &buf_m, &buf_d, &buf_w); /* 前日 */ 134 printf("年:%d\n月:%d\n日:%d\n曜日:%d\n", buf_y, buf_m, buf_d, buf_w); 135 if (buf_w == 0) 136 { 137 flg = O_HOLIDAY; 138 } 139 else 140 { 141 /* NOP */ 142 } 143 } while (P_HOLIDAY == d_holiday(buf_y, buf_m, buf_d, buf_w) || buf_w != 0); /* 前日が祝日の間ループ */ 144 145 /* 国民の休日の判定 */ 146 buf_y = buf_y2 = y; 147 buf_m = buf_m2 = m; 148 buf_d = buf_d2 = d; 149 buf_w = buf_w2 = w; 150 day_before(&buf_y, &buf_m, &buf_d, &buf_w); /* 前日 */ 151 day_next(&buf_y2, &buf_m2, &buf_d2, &buf_w2); /* 翌日 */ 152 if (P_HOLIDAY == d_holiday(buf_y, buf_m, buf_d, buf_w) 153 && P_HOLIDAY == d_holiday(buf_y2, buf_m2, buf_d2, buf_w2)) /* 前日と翌日が祝日だったら */ 154 { 155 flg = N_HOLIDAY; 156 } 157 else 158 { 159 /* NOP */ 160 } 161 } 162 if (flg == 1) 163 { 164 return P_HOLIDAY; 165 } 166 else if (flg == 2) 167 { 168 return O_HOLIDAY; 169 } 170 else if (flg == 3) 171 { 172 return N_HOLIDAY; 173 } 174 else 175 { 176 return 0; 177 } 178 179} 180 181void print_holiday(int y, int m, int d, int w) 182{ 183 if (m == 1 && d == 1) 184 { 185 puts("元日"); 186 } 187 else if (m == 1 && w == 1 && 8 <= d && d <= 14) 188 { 189 puts("成人の日"); 190 } 191 else if (m == 2 && d == 11) 192 { 193 puts("建国記念の日"); 194 } 195 else if (m == 3 && d == (int)(20.8431 + 0.242194 196 * (y - 1980) - (y - 1980) / 4)) 197 { 198 puts("春分の日"); 199 } 200 else if (m == 4 && d == 29) 201 { 202 puts("昭和の日"); 203 } 204 else if (m == 5 && d == 3) 205 { 206 puts("憲法記念日"); 207 } 208 else if (m == 5 && d == 4) 209 { 210 puts("みどりの日"); 211 } 212 else if (m == 5 && d == 5) 213 { 214 puts("こどもの日"); 215 } 216 else if (m == 7 && w == 1 && 15 <= d && d <= 21) 217 { 218 puts("海の日"); 219 } 220 else if (m == 8 && d == 11) 221 { 222 puts("山の日"); 223 } 224 else if (m == 9 && w == 1 && 15 <= d && d <= 21) 225 { 226 puts("敬老の日"); 227 } 228 else if (m == 9 && d == (int)(23.2488 + 0.242194 229 * (y - 1980) - (y - 1980) / 4)) 230 { 231 puts("秋分の日"); 232 } 233 else if (m == 10 && w == 1 && 8 <= d && d <= 14) 234 { 235 puts("体育の日"); 236 } 237 else if (m == 11 && d == 3) 238 { 239 puts("文化の日"); 240 } 241 else if (m == 11 && d == 23) 242 { 243 puts("勤労感謝の日"); 244 } 245 else if (m == 12 && d == 23) 246 { 247 puts("天皇誕生日"); 248 } 249 else 250 { 251 puts("エラー"); 252 } 253} 254 255void day_before(int *y, int *m, int *d, int *w) 256{ 257 if (*m == 1 && *d == 1) /* 1月1日だったら */ 258 { 259 /* 前年の12月31日 */ 260 (*y)--; 261 *m = 12; 262 *d = 31; 263 } 264 else if (*d == 1) /* 1日だったら */ 265 { 266 /* 前月の末日 */ 267 (*m)--; 268 *d = c_lday(*y, *m); 269 } 270 else 271 { 272 (*d)--; 273 } 274 /* 前日の曜日を求める処理 */ 275 if (*w == 0) 276 { 277 *w = 6; 278 } 279 else 280 { 281 (*w)--; 282 } 283} 284 285void day_next(int *y, int *m, int *d, int *w) 286{ 287 if (*m == 12 && *d == 31) /* 12月31日だったら */ 288 { 289 /* 翌年の1月1日 */ 290 (*y)++; 291 *m = 1; 292 *d = 1; 293 } 294 else if (*d == c_lday(*y, *m)) /* 直前までの条件を除く末日だったら */ 295 { 296 /* 翌月の1日 */ 297 (*m)++; 298 *d = 1; 299 } 300 else 301 { 302 (*d)++; 303 } 304 /* 翌日の曜日を求める処理 */ 305 if (*w == 6) 306 { 307 *w = 0; 308 } 309 else 310 { 311 (*w)++; 312 } 313} 314
**実行結果** 年、月を入力後にその月のカレンダーを表示します 年を2016~2099の範囲、月を1~12の範囲で入力して下さい 年と月の間を半角スペースで区切って下さい 例:2016 1/2099 12 年と月の入力:2020 2 . . . 年:2011 月:10 日:1 曜日:6 年:2011 月:9 日:30 曜日:5 年:2011 月:9 日:29 曜日:4 年:2011 月:9 日:28 曜日:3 年:2011 月:9 日:27 曜日:2 年:2011 月:9 日:26 曜日:1

C言語の学習のために作成しているのですが、上記のソースでどの部分をどう修正すればよいか教えていただけるとありがたいです
冗長なコードや効率が悪いコードの記述があったらそこも指摘していただけると嬉しいです

追記 2017/06/19
すみません、あれから関数d_holidayを書き直して、いろいろ試してみたのですがどうしても国民の休日の判定の部分でstack overflowになってしまいます。
追記で質問し直したかったのですが字数制限で投稿できなかったので、質問し直します。
皆様、回答ありがとうございました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

print_calendar.cのみですがループしない様に変更してみました。 gccですので多少異なるやも。

c

1#include <stdio.h> 2#include "calendar.h" 3 4int c_lday(int y, int m); /* 末日を求める関数 */ 5int c_dow(int y, int m, int d); /* 任意の日付の曜日を求める関数 */ 6int d_holiday(int y, int m, int d, int w); /* 祝日、振替休日、国民の休日の判定をする関数 */ 7int n_holiday(int y, int m, int d, int w); /* 国民の休日の判定をする関数 */ 8void print_holiday(int y, int m, int d, int w); /* 国民の祝日を表示する関数 */ 9void day_before(int *y, int *m, int *d, int *w); /* 前日を返す関数 */ 10void day_next(int *y, int *m, int *d, int *w); /* 翌日を返す関数 */ 11 12void print_calendar(int *y, int *m) 13{ 14 int day; /* 日にち */ 15 int dow; /* 曜日 */ 16 int const lday = c_lday(*y, *m); /* 末日 */ 17 const char p_dow[7][8] = { "日", "月", "火", "水", "木", "金", "土" }; /* 曜日表示用 */ 18 int hol_flg; /* 祝日、振替休日、国民の休日フラグ */ 19 20 ///* 初日の曜日を求める */ 21 //day = 1; 22 //dow = c_dow(*y, *m, day); 23 puts("****************************"); 24 printf(" %d年%d月のカレンダー\n", *y, *m); 25 puts("****************************"); 26 for (day = 1; day <= lday; day++) /* 初日から末日までループ */ 27 { 28 dow = c_dow(*y, *m, day); /* 当日の曜日を求める */ 29 hol_flg = d_holiday(*y, *m, day, dow); /* 祝日判定 */ 30 31 /* カレンダーの表示 */ 32 printf("%2d日 (%s) ", day, p_dow[dow]); 33 if (hol_flg == P_HOLIDAY) 34 { 35 print_holiday(*y, *m, day, dow); 36 } 37 else if (hol_flg == O_HOLIDAY) 38 { 39 puts("振替休日"); 40 } 41 else if (hol_flg == N_HOLIDAY) 42 { 43 puts("国民の休日"); 44 } 45 else 46 { 47 putchar('\n'); 48 } 49 /* 曜日を進める処理 後で追加 */ 50 } 51 getchar(); /* コンソールの終了待機処理 */ 52} 53 54int c_lday(int y, int m) 55{ 56 if (m == 2) /* 2月なら */ 57 { 58 /* うるう年の判定 */ 59 if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) /* 400で割り切れるか、4で割り切れるが100で割り切れない年だったら */ 60 { 61 return 29; 62 } 63 else 64 { 65 return 28; 66 } 67 } 68 else if (m == 4 || m == 6 || m == 9 || m == 11) /* 直前までの条件を除く4月、6月、9月、11月だったら */ 69 { 70 return 30; 71 } 72 else 73 { 74 return 31; 75 } 76} 77 78int c_dow(int y, int m, int d) 79{ 80 if (m == 1 || m == 2) 81 { 82 y--; 83 m += 12; 84 return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d) % 7; 85 } 86 else 87 { 88 return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d) % 7; 89 } 90} 91 92int d_holiday(int y, int m, int d, int w) 93{ 94 /* 引数で受け取った値をローカルにコピー */ 95 int buf_y, buf_y2; 96 int buf_m, buf_m2; 97 int buf_d, buf_d2; 98 int buf_w, buf_w2; 99 int flg; 100 buf_y = y; 101 buf_m = m; 102 buf_d = d; 103 buf_w = w; 104 105 /* 国民の祝日の判定 */ 106 if ( n_holiday(buf_y, buf_m, buf_d, buf_w) ) 107 { 108 return P_HOLIDAY; 109 } 110 else if (w != 0 || w != 6) /* 祝日か土日ではなかったら */ 111 { 112 day_before(&buf_y, &buf_m, &buf_d, &buf_w); /* 前日 */ 113 printf("年:%d月:%d日:%d曜日:%d\n", buf_y, buf_m, buf_d, buf_w); 114 115 /* 振替休日の判定 */ 116 if (buf_w == 0 && P_HOLIDAY == d_holiday(buf_y, buf_m, buf_d, buf_w)) 117 { 118 return O_HOLIDAY; 119 } 120 121 /* 国民の休日の判定 */ 122 buf_y2 = y; 123 buf_m2 = m; 124 buf_d2 = d; 125 buf_w2 = w; 126 day_next(&buf_y2, &buf_m2, &buf_d2, &buf_w2); /* 翌日 */ 127 128 if (P_HOLIDAY == n_holiday(buf_y, buf_m, buf_d, buf_w) 129 && P_HOLIDAY == n_holiday(buf_y2, buf_m2, buf_d2, buf_w2)) /* 前日と翌日が祝日だったら */ 130 { 131 return N_HOLIDAY; 132 } 133 else 134 { 135 /* NOP */ 136 } 137 } 138 139 return 0; 140} 141 142int n_holiday(int y, int m, int d, int w) 143{ 144 /* 国民の祝日の判定 */ 145 if ((m == 1 && d == 1) /* 1/1 元日 */ 146 || (m == 1 && w == 1 && 8 <= d && d <= 14) /* 1月第2月曜 成人の日 */ 147 || (m == 2 && d == 11) /* 2/11 建国記念の日 */ 148 || (m == 3 && d == (int)(20.8431 + 0.242194 149 * (y - 1980) - (y - 1980) / 4)) /* 3/20付近 春分の日 */ 150 || (m == 4 && d == 29) /* 4/29 昭和の日 */ 151 || (m == 5 && d == 3) /* 5/3 憲法記念日 */ 152 || (m == 5 && d == 4) /* 5/4 みどりの日 */ 153 || (m == 5 && d == 5) /* 5/5 こどもの日 */ 154 || (m == 7 && w == 1 && 15 <= d && d <= 21) /* 7月第3月曜 海の日 */ 155 || (m == 8 && d == 11) /* 8/11 山の日 */ 156 || (m == 9 && w == 1 && 15 <= d && d <= 21) /* 9月第3月曜 敬老の日 */ 157 || (m == 9 && d == (int)(23.2488 + 0.242194 158 * (y - 1980) - (y - 1980) / 4)) /* 9/23付近 秋分の日 */ 159 || (m == 10 && w == 1 && 8 <= d && d <= 14) /* 10月第2月曜 体育の日 */ 160 || (m == 11 && d == 3) /* 11/3 文化の日 */ 161 || (m == 11 && d == 23) /* 11/23 勤労感謝の日 */ 162 || (m == 12 && d == 23)) /* 12/23 天皇誕生日 */ 163 { 164 return P_HOLIDAY; 165 } 166 return 0; 167} 168 169void print_holiday(int y, int m, int d, int w) 170{ 171 if (m == 1 && d == 1) 172 { 173 puts("元日"); 174 } 175 else if (m == 1 && w == 1 && 8 <= d && d <= 14) 176 { 177 puts("成人の日"); 178 } 179 else if (m == 2 && d == 11) 180 { 181 puts("建国記念の日"); 182 } 183 else if (m == 3 && d == (int)(20.8431 + 0.242194 184 * (y - 1980) - (y - 1980) / 4)) 185 { 186 puts("春分の日"); 187 } 188 else if (m == 4 && d == 29) 189 { 190 puts("昭和の日"); 191 } 192 else if (m == 5 && d == 3) 193 { 194 puts("憲法記念日"); 195 } 196 else if (m == 5 && d == 4) 197 { 198 puts("みどりの日"); 199 } 200 else if (m == 5 && d == 5) 201 { 202 puts("こどもの日"); 203 } 204 else if (m == 7 && w == 1 && 15 <= d && d <= 21) 205 { 206 puts("海の日"); 207 } 208 else if (m == 8 && d == 11) 209 { 210 puts("山の日"); 211 } 212 else if (m == 9 && w == 1 && 15 <= d && d <= 21) 213 { 214 puts("敬老の日"); 215 } 216 else if (m == 9 && d == (int)(23.2488 + 0.242194 217 * (y - 1980) - (y - 1980) / 4)) 218 { 219 puts("秋分の日"); 220 } 221 else if (m == 10 && w == 1 && 8 <= d && d <= 14) 222 { 223 puts("体育の日"); 224 } 225 else if (m == 11 && d == 3) 226 { 227 puts("文化の日"); 228 } 229 else if (m == 11 && d == 23) 230 { 231 puts("勤労感謝の日"); 232 } 233 else if (m == 12 && d == 23) 234 { 235 puts("天皇誕生日"); 236 } 237 else 238 { 239 puts("エラー"); 240 } 241} 242 243void day_before(int *y, int *m, int *d, int *w) 244{ 245 if (*m == 1 && *d == 1) /* 1月1日だったら */ 246 { 247 /* 前年の12月31日 */ 248 (*y)--; 249 *m = 12; 250 *d = 31; 251 } 252 else if (*d == 1) /* 1日だったら */ 253 { 254 /* 前月の末日 */ 255 (*m)--; 256 *d = c_lday(*y, *m); 257 } 258 else 259 { 260 (*d)--; 261 } 262 /* 前日の曜日を求める処理 */ 263 if (*w == 0) 264 { 265 *w = 6; 266 } 267 else 268 { 269 (*w)--; 270 } 271} 272 273void day_next(int *y, int *m, int *d, int *w) 274{ 275 if (*m == 12 && *d == 31) /* 12月31日だったら */ 276 { 277 /* 翌年の1月1日 */ 278 (*y)++; 279 *m = 1; 280 *d = 1; 281 } 282 else if (*d == c_lday(*y, *m)) /* 直前までの条件を除く末日だったら */ 283 { 284 /* 翌月の1日 */ 285 (*m)++; 286 *d = 1; 287 } 288 else 289 { 290 (*d)++; 291 } 292 /* 翌日の曜日を求める処理 */ 293 if (*w == 6) 294 { 295 *w = 0; 296 } 297 else 298 { 299 (*w)++; 300 } 301} 302

投稿2017/06/13 01:08

編集2017/06/13 01:09
A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

連投すみません。
回答が回答になっていなくて申し訳なくて...

d_holidayが再帰的に呼び出される設計なのですね。
以下のコードがおかしいです。

C

1else if (w != 0 || w != 6) /* 祝日が土日ではなかったら */

『wが0でないか、wが6でないとき』つまり、毎回trueですね。


コードに意味を持たせることで、バグの発見率は一気にあがります。
例えば、次のような関数を導入してはいかがでしょうか。

C

1bool isSunday(int w) { 2 return w == 0; 3}

また、冗長なコードも、とりあえずエラーフラグに関して。
err_flgをfalseに初期化すれば、err_flg = false;を複数個所省けます。
また、

C

1/* エラー処理 */ 2if (err_flg == true)

この==trueは完全に冗長です。

投稿2017/06/12 17:07

編集2017/06/12 17:18
LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sonozaki_SZ

2017/06/12 20:45

回答ありがとうございます 私事なんですが論理式が苦手でして毎回そこがバグの原因になってしまうんですよね… 修正後に正常にプログラムが動作し次第修正済みのソースを追記したいと思います
guest

0

後学のためにも、まずはデバッグしやすいコードの改良をお勧めします。
年月日/曜日を構造体にまとめたり、値渡しを活用したり、関数を見直したりする必要があります。
その中で自然とバグも浮き彫りになるかと。

投稿2017/06/12 15:10

LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sonozaki_SZ

2017/06/12 15:18

回答ありがとうございます ポインタまでは勉強済みなのですが構造体はまだ勉強中でして、どう記述したらいいか教えていただきたいです それと現在は柴田望洋氏の新明解C言語入門編で勉強しているのですが 他に独学で勉強する際に参考になる書籍等を教えていただけたら幸いです
LouiS0616

2017/06/12 15:28

構造体は、複数の関係ある変数をまとめるものです。 次のサイトが参考になります。 http://9cguide.appspot.com/16-01.html 書籍は、そうですね... 上記の『苦しんで覚えるC言語』が書籍化されているので、読んでみてもいいかもしれませんね。 特にこれ!というお勧めが出来なくてすみません。
mugicya

2017/06/12 15:28

柴田望洋さんの書籍でいいとおもいます。 それが理解できたら、あとは応用になるので、その分野に相応しい本を探しましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問