###前提・実現したいこと
先日は質問への回答ありがとうございました。
続いてC言語で、入力された年の1年カレンダーを表示するプログラムを作成しています。
###発生している問題・エラーメッセージ
入力値からカレンダーの出力もうまくいっているのですが、
日数の書き出し部分あたりに同じコードを何度も使ってしまっています。
この繰り返しの部分をもっとスッキリさせる方法はないでしょうか。
下記コード上に記述した部分が繰り返し使っているので関数にしてしまいたいのですが、
すでに関数を使ってしまっているので関数内関数?になってしまうためかうまくいきません。
(C言語で関数内関数は使えないとどこかのサイトで見ました)
関数の中で関数を使う方法や、
それ以外の方法がありましたらアドバイスいただけると幸いです。
###ソースコード
lang
1#pragma warning(disable:4996) 2#include <stdio.h> 3#include <stdlib.h> 4 5//プロトタイプ宣言 6int uru_cal(int u_y); 7int dow(int wy, int wm); 8void writeblank(int b_dos); 9int writedays(int eom, int res_dow); 10int writedays2(int eom, int res_dow, int now); 11 12 13struct result{ //構造体result宣言 14 int res_month; 15 int res_dow; 16 int eom; 17 int now; 18}; 19 20int main(void){ 21 22 int year = 0; 23 int month = 0; 24 int uru = 0; 25 int i = 0; 26 int j = 0; 27 int res_uru = 0; 28 int res_dow = 0; 29 int now = 0; 30 int ent = 0; 31 32 printf("表示したい年を入力してください(1900年~) → \n"); 33 scanf("%d", &year); 34 35 if (1900 >= year){ //入力チェック 36 printf("数値が正しくありません。"); 37 exit(1); 38 } 39 40 41 res_uru = uru_cal(year); //うるう年の計算 42 43 struct result month_a[12] = { //構造体の初期化 44 { 1, res_dow, 31, now }, //[0] 45 { 2, res_dow, res_uru, now },//[1]うるう関数からの戻り値を代入 46 { 3, res_dow, 31, now }, //[2] 47 { 4, res_dow, 30, now }, //[3] 48 { 5, res_dow, 31, now }, //[4] 49 { 6, res_dow, 30, now }, //[5] 50 { 7, res_dow, 31, now }, //[6] 51 { 8, res_dow, 31, now }, //[7] 52 { 9, res_dow, 30, now }, //[8] 53 { 10, res_dow, 31, now }, //[9] 54 { 11, res_dow, 30, now }, //[10] 55 { 12, res_dow, 31, now }, //[11] 56 }; 57 58 for (i = 0, month = 0; i < 11; i++, month++){ //配列にres_dowを代入 59 month_a[i].res_dow = dow(year, month); //dow関数 60 61 } 62 63 printf("=============%d年のカレンダー=============\n", year); 64 65 66 /*1月~3月*/ 67 for (j = 0; j < 3; j++){ 68 printf(" [%d月] ", month_a[j].res_month); 69 } 70 71 printf("\n"); 72 73 74 printf(" 日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n"); 75 for (j = 0; j < 3; j++){ 76 77 /*繰り返し使っている部分↓*/ 78 writeblank(month_a[j].res_dow); //月の始めのブランクを出力 79 80 month_a[j].now = writedays(month_a[j].eom, month_a[j].res_dow); //eomとres_dowを使って日付を出力 81 82 ent++; 83 84 if (ent == 3){ 85 printf("\n"); 86 ent = 0; 87 } 88 else{ 89 printf(" "); 90 } 91 /*繰り返し使っている部分↑*/ 92 } 93 94 for (i = 0; i < 5; i++){ 95 96 /*繰り返し使っている部分↓*/ 97 for (j = 0; j < 3; j++){ 98 99 month_a[j].now = writedays2(month_a[j].eom, month_a[j].res_dow, month_a[j].now); //eomとnowを使って日付を出力 100 101 ent++; 102 103 if (ent == 3){ 104 printf("\n"); 105 ent = 0; 106 } 107 else{ 108 printf(" "); 109 } 110 } 111 /*繰り返し使っている部分↑*/ 112 } 113 114 /*4月~5月*/ 115 for (j = 3; j < 6; j++){ 116 printf(" [%d月] ", month_a[j].res_month); 117 } 118 119 printf("\n"); 120 121 122 printf(" 日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n"); 123 124 for (j = 3; j < 6; j++){ 125 126 /*第1週目*3か月分*/ 127 writeblank(month_a[j].res_dow); //月の始めのブランクを出力 128 129 month_a[j].now = writedays(month_a[j].eom, month_a[j].res_dow); //eomとres_dowを使って日付を出力 130 131 ent++; 132 133 if (ent == 3){ 134 printf("\n"); 135 ent = 0; 136 } 137 else{ 138 printf(" "); 139 } 140 } 141 142 for (i = 0; i < 5; i++){ 143 144 for (j = 3; j < 6; j++){ 145 146 month_a[j].now = writedays2(month_a[j].eom, month_a[j].res_dow, month_a[j].now); //eomとnowを使って日付を出力 147 148 ent++; 149 150 if (ent == 3){ 151 printf("\n"); 152 ent = 0; 153 } 154 else{ 155 printf(" "); 156 } 157 } 158 } 159 160 /*7月~9月*/ 161 for (j = 6; j < 9; j++){ 162 printf(" [%d月] ", month_a[j].res_month); 163 } 164 165 printf("\n"); 166 167 printf(" 日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n"); 168 169 for (j = 6; j < 9; j++){ 170 171 /*第1週目*3か月分*/ 172 writeblank(month_a[j].res_dow); //月の始めのブランクを出力 173 174 month_a[j].now = writedays(month_a[j].eom, month_a[j].res_dow); //eomとres_dowを使って日付を出力 175 176 ent++; 177 178 if (ent == 3){ 179 printf("\n"); 180 ent = 0; 181 } 182 else{ 183 printf(" "); 184 } 185 } 186 187 for (i = 0; i < 5; i++){ 188 189 for (j = 6; j < 9; j++){ 190 191 month_a[j].now = writedays2(month_a[j].eom, month_a[j].res_dow, month_a[j].now); //eomとnowを使って日付を出力 192 193 ent++; 194 195 if (ent == 3){ 196 printf("\n"); 197 ent = 0; 198 } 199 else{ 200 printf(" "); 201 } 202 } 203 } 204 205 /*10月~12月*/ 206 for (j = 9; j < 12; j++){ 207 printf(" [%d月] ", month_a[j].res_month); 208 } 209 210 printf("\n"); 211 212 213 printf(" 日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n"); 214 215 for (j = 9; j < 12; j++){ 216 217 /*第1週目*3か月分*/ 218 writeblank(month_a[j].res_dow); //月の始めのブランクを出力 219 220 month_a[j].now = writedays(month_a[j].eom, month_a[j].res_dow); //eomとres_dowを使って日付を出力 221 222 ent++; 223 224 if (ent == 3){ 225 printf("\n"); 226 ent = 0; 227 } 228 else{ 229 printf(" "); 230 } 231 } 232 233 for (i = 0; i < 5; i++){ 234 235 for (j = 9; j < 12; j++){ 236 237 month_a[j].now = writedays2(month_a[j].eom, month_a[j].res_dow, month_a[j].now); //eomとnowを使って日付を出力 238 239 ent++; 240 241 if (ent == 3){ 242 printf("\n"); 243 ent = 0; 244 } 245 else{ 246 printf(" "); 247 } 248 } 249 } 250 251 252 253} //main終わり 254 255//関数宣言 256int uru_cal(int u_y){ //関数うるう計算 257 258 int res_uru = 0; 259 260 if (u_y % 4 == 0 && (u_y % 100 != 0 || u_y % 400 == 0)){ //うるう年の判定 261 res_uru = 29; //月の終わりの日付を29に設定 262 263 } 264 else{ 265 res_uru = 28; //月の終わりの日付を28に設定 266 } 267 268 return res_uru; 269}; 270 271int dow(int wy, int wm){ //dow関数 272 273 int dayofweek = 0; 274 wm += 1; 275 276 277 if (wm == 1 || wm == 2) { 278 wy--; 279 wm += 12; 280 } 281 282 return dayofweek = (wy + wy / 4 - wy / 100 + wy / 400 + (13 * wm + 8) / 5 + 1) % 7; //毎月1日の曜日を計算; 283} 284 285 286void writeblank(int b_dow){ //writeblank関数 287 288 289 290 int blank = 0; 291 292 for (blank = 0; blank < b_dow; blank++){ //先頭曜日まで空白 293 printf(" "); 294 } 295} 296 297 298int writedays(int eom, int res_dow){ 299 300 int day = 0; 301 int nextday = 0; 302 303 for (day = 1; day <= 7 - res_dow; day++){ 304 printf(" %2d", day); 305 nextday = day; 306 } 307 308 return nextday; //nextdayを返す 309} 310 311int writedays2(int eom, int res_dow, int now){ 312 int day = 0; 313 int r = 0; 314 int e = 0; 315 int nextday = now; 316 317 318 319 for (day = nextday + 1, r = 0; r <= 6; day++, r++){ 320 321 if (day <= eom){ 322 printf(" %2d", day); 323 nextday = day; 324 } 325 else{ 326 printf(" "); 327 } 328 } 329 330 331 return nextday; 332} 333
###補足情報(言語/FW/ツール等のバージョンなど)
※課題として構造体をあえて使っています
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/06/13 06:15