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

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

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

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

Q&A

解決済

4回答

1250閲覧

C言語 カレンダー コンソールに表示した(3か月ずつなど

kokok

総合スコア145

C

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

0グッド

0クリップ

投稿2019/08/02 07:24

編集2019/08/05 01:44

c

1 2#pragma warning(disable: 4996) 3#include<stdio.h> 4 5#define ROW_SIZE 6 //カレンダーの行のサイズ 6#define SPRING_EQ 0 7#define FALL_EQ 1 8#define BIRTH_MARK 0x80// 誕生日マーク 9#define TRANS_MARK 0x40// 振替祝日マーク 10#define HOLI_MARK 0x20// 祝日マーク 11#define MAX_HOLI_TBL 4 //祝日テーブルの最大 12 13 14enum M_LIST { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOW, DEC, N_MONTH }; 15enum W_LIST { SUN, MON, TUE, WED, THU, FRI, SAT, N_WEEK }; 16int monthdays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //月の日数 17char* weeks[] = { "日","月","火","水","木","金","土" }; 18//**************************************************** 19// 20// 祝日のデータテーブル 21// 22 23char holidays[N_MONTH][MAX_HOLI_TBL] = { 24 {1,-2,0,0}, // 1月、元旦、成人の日 25 {11,23,0,0}, // 2月、建国記念日、令和天皇誕生日 26 {21,0,0,0}, // 3月、春分の日(計算で求める) 27 {29,0,0,0}, // 4月、昭和の日 28 {3,4,5,0}, // 5月、憲法記念日、みどりの日、子供の日 29 { 0,0,0,0}, // 6月、なし 30 {-3,0,0,0}, // 7月、海の日 31 {11,0,0,0}, // 8月、山の日 32 {-3,23,0,0}, // 9月、敬老の日、秋分の日(計算で求める) 33 {-2,0,0,0}, // 10月、体育の日 34 {3,23,0,0}, // 11月、文化の日、勤労感謝の日 35 { 0,0,0,0} // 12月、なし 36}; 37 38//プロトタイプの宣言 39int januaryoneday(int year); 40int leapyear(int year); 41int calendarmake(char calendar[N_MONTH][ROW_SIZE][N_WEEK], int week, int year, int birthmon, int birthday); 42void calendarprint(char calendar[N_MONTH][ROW_SIZE][N_WEEK], int year, int display); 43void spraut(int yy); 44 45 46int main(void) { 47 48 49 char calendar[N_MONTH][ROW_SIZE][N_WEEK] = { 0 }; // カレンダーの多次元配列 50 51 int year; //入力された西暦 52 //int month; //入力された月 53 //int day; //入力された日 54 int week; // //入力された西暦の1月1日の曜日 55 int judgment; //入力された値がうるう年だったかどうか 56 int sumday; // 入力された西暦までの日数の合計 57// int birthw; //入力された誕生日の曜日 58 int monthdaysum = 0; // 入力された誕生日の月までの合計の日数 59 int birthmon; //入力された誕生月 60 int birthday; //入力された誕生日 61 int display; //入力された表示方法 62 63 printf("西暦を入力してください"); 64 scanf("%d", &year); 65 66 printf("誕生日を入力してください"); 67 scanf("%d %d", &birthmon, &birthday); 68 69 printf("カレンダーの表示3行か4行か"); 70 scanf("%d", &display); 71 72 week = januaryoneday(year); //入力された西暦の1月1日の曜日を取得 73 74 //printf("%s\n", weeks[week]); //入力された西暦の1月1日の曜日を表示 75 76 judgment = leapyear(year); //うるう年の判定結果を取得 77 78 79 monthdays[FEB] = (judgment == 0) ? 29 : 28; // うるう年であれば2月を29日に変更 80 81 82 83 sumday = ((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400); //入力された西暦までの日数の合計 84 85 /*for (int i = JAN; i < month - 1; i++) { //入力された誕生日の月までの合計の日数 86 87 monthdaysum += monthdays[i]; 88 89 } 90 91 birthw = (sumday + monthdaysum + day) % 7; // 入力された誕生日までの合計の日数 の曜日を取得 92 93 printf("%s", weeks[birthw]); //入力された誕生日の曜日を表示 94 95 */ 96 week = calendarmake(calendar, week, year, birthmon, birthday); 97 98 //printf("%s\n", weeks[week]); 99 100 101 spraut(year); //春分の日と秋分の日を設定 102 103 calendarprint(calendar, year, display); //カレンダーの表示 104 105} 106 107 108//入力された西暦の1月1日の曜日を返す 109int januaryoneday(int year) { 110 111 int sumday; // 入力された西暦までの累計日数 112 int dayw; // 曜日計算 113 114 sumday = ((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400); //入力された1月1日までの日数 115 116 dayw = (sumday + 1) % 7; 117 118 return dayw; 119} 120 121 122//入力された西暦がうるう年かの判定 123int leapyear(int year) { 124 125 int leap; 126 127 leap = (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) ? 0 : -1; //うるう年なら0を 違うなら-1 を 128 129 return leap; 130} 131 132 133//カレンダーを作る 134int calendarmake(char calendar[N_MONTH][ROW_SIZE][N_WEEK], int week, int year, int birthmon, int birthday) { 135 136 int month; // 1月から12月 137 int row; //カレンダーの行 138 int day;//月の日にち 139 int monday_cnt; 140 int holiday_cnt; 141 142 143 for (month = JAN; month <= DEC; month++) { 144 145 row = 0; //月ごとに初期化 146 day = 1; //月ごとに初期化 147 monday_cnt = 0;// 月曜日カウント 148 holiday_cnt = 0; // 祝日カウント 149 150 151 while (day <= monthdays[month]) 152 { 153 154 calendar[month][row][week] |= day; //現在の日付のビットを立てる 155 156 157 if (week == MON) { 158 monday_cnt++; //月曜日なら1増やす 159 } 160 161 162 if (holidays[month][holiday_cnt] == day) { //固定祝日だったら 163 164 calendar[month][row][week] |= HOLI_MARK; //固定祝日のビットを立てる 165 holiday_cnt++; 166 167 if ((week == SUN) || (calendar[month][row][week] & TRANS_MARK)) { //固定祝日が日曜日またはすでに振替休日の場合 168 169 calendar[month][row][week + 1] |= TRANS_MARK; 170 } 171 } 172 173 if ((holidays[month][holiday_cnt] < 0) && (holidays[month][holiday_cnt] * -1) == monday_cnt) { 174 175 calendar[month][row][week] |= HOLI_MARK; //固定でない祝日のビットを立てる 176 177 holiday_cnt++; 178 } 179 180 if (week > TUE) { 181 182 if (calendar[month][row][week] & HOLI_MARK && calendar[month][row][week - 2] & HOLI_MARK) { 183 184 calendar[month][row][week - 1] |= HOLI_MARK; 185 } 186 } 187 188 189 if (month == birthmon - 1 && day == birthday) { //引数で渡された誕生日だったら誕生日のマーク入れる 190 191 calendar[month][row][week] |= BIRTH_MARK; 192 } 193 194 week++; 195 day++; 196 197 if (week > SAT) { 198 199 week = SUN; 200 row++; 201 } 202 } 203 } 204 return week; //最後の曜日を返す 205} 206 207 208//カレンダーを表示する 209void calendarprint(char calendar[N_MONTH][ROW_SIZE][N_WEEK], int year, int display) { 210 211 int month; //月のループ 212 int row; //週のループ 213 int col;//曜日のループ 214 215 216 printf("%5d年\n", year); // 入力された年を表示 217 218 for (month = JAN; month <= DEC; month++) { 219 220 221 printf(" %2d月\n", month + 1); 222 printf("\n"); 223 224 for (int i = 0; i <= SAT; i++) { 225 226 printf(" %2s ", weeks[i]); //曜日の表示 227 } 228 229 printf("\n"); 230 231 for (row = 0; row < ROW_SIZE; row++) { 232 233 for (col = 0; col <= SAT; col++) { 234 235 if (calendar[month][row][col] != 0) //日数が0でなければ 236 { 237 238 if (calendar[month][row][col] & HOLI_MARK) { 239 printf("*"); 240 } 241 else if (calendar[month][row][col] & TRANS_MARK) { 242 printf("+"); 243 } 244 else if (calendar[month][row][col] & BIRTH_MARK) { 245 printf("&"); 246 247 } 248 else { 249 250 printf(" "); 251 } 252 253 printf("%2d ", calendar[month][row][col] & 0x1F); 254 } 255 256 else { //日数が0なら 257 printf(" "); 258 } 259 } 260 printf("\n"); 261 } 262 printf("\n"); 263 } 264} 265 266//春分と秋分の日を求める 267 268void spraut(int year) { 269 270 int yy; 271 int springEQ; // 求める春分の日 272 int fallEQ; // 求める秋分の日 273 yy = year; 274 275 if (yy <= 1899) { 276 springEQ = (int)(19.8277 + 0.242194 * (yy - 1980) - ((yy - 1983) / 4)); 277 fallEQ = (int)(22.2588 + 0.242194 * (yy - 1980) - ((yy - 1983) / 4)); 278 } 279 else if (yy >= 1900 && yy <= 1979) { 280 springEQ = (int)(20.8357 + 0.242194 * (yy - 1980) - ((yy - 1983) / 4)); 281 fallEQ = (int)(23.2588 + 0.242194 * (yy - 1980) - ((yy - 1983) / 4)); 282 } 283 else if (yy >= 1980 && yy <= 2099) { 284 springEQ = (int)(20.8431 + 0.242194 * (yy - 1980) - ((yy - 1980) / 4)); 285 fallEQ = (int)(23.2488 + 0.242194 * (yy - 1980) - ((yy - 1980) / 4)); 286 } 287 else if (yy >= 2100) { 288 springEQ = (int)(21.851 + 0.242194 * (yy - 1980) - ((yy - 1980) / 4)); 289 fallEQ = (int)(24.2488 + 0.242194 * (yy - 1980) - ((yy - 1980) / 4)); 290 } 291 holidays[MAR][SPRING_EQ] = springEQ; // 春分の日を入れる 292 holidays[SEP][FALL_EQ] = fallEQ; // 秋分の日を入れる 293} 294 295 296

コンソールにカレンダーを縦 一列に表示することは出来たので、横にも表示させたいと思ったのですが、どうすればいいのか思いつきませんでした。

1 2 3
4 5 6
7 8 9
10 11 12

このように表示したりしたいのですが、アドバイス頂けると幸いです。

-----追記-------

c

1//カレンダーを表示する 2void calendarprint(char calendar[N_MONTH][ROW_SIZE][N_WEEK], int year, int display) { 3 4 int month; //月のループ 5 int row; //週のループ 6 int col;//曜日のループ 7 8 9 printf("%5d年\n", year); // 入力された年を表示 10 11 for (month = JAN; month <= DEC; month+=display) { 12 for (int m = month, dis = 0; m < N_MONTH && dis < display; m++, dis++) { 13 14 printf(" %2d月 ", m + 1); 15 } 16 printf("\n\n"); 17 for (int m = month, dis = 0; m < N_MONTH && dis < display; m++, dis++) { 18 for (int i = 0; i <= SAT; i++) { 19 20 printf(" %2s ", weeks[i]); //曜日の表示 21 if (i == SAT) { 22 printf(" "); 23 } 24 } 25 } 26 printf("\n"); 27 28 for (row = 0; row < ROW_SIZE; row++) { 29 printf("\n"); 30 for(int m = month, dis = 0; m < N_MONTH && dis < display; m++, dis++){ 31 32 for (col = 0; col <= SAT; col++) { 33 34 if (calendar[month][row][col] != 0) //日数が0でなければ 35 { 36 37 if (calendar[month][row][col] & HOLI_MARK) { 38 printf("*"); 39 } 40 else if (calendar[month][row][col] & TRANS_MARK) { 41 printf("+"); 42 } 43 else if (calendar[month][row][col] & BIRTH_MARK) { 44 printf("&"); 45 } 46 else { 47 48 printf(" "); 49 } 50 printf("%2d ", calendar[month][row][col] & 0x1F); 51 } 52 else { //日数が0なら 53 printf(" "); 54 } 55 if (col == SAT) { 56 57 printf(" "); 58 } 59 } 60 } 61 printf("\n"); 62 } 63 printf("\n"); 64 } 65} 66

カレンダーを表示の部分を回答を参考に自分なりに書いてみました。

しかし、表示の仕方を

1 2 7 8
3 4 9 10
5 6 11 12

上記ののように表示をしたいのですが、なかなかうまくいきません。

追加でアドバイス頂けると幸いです。

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

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

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

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

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

guest

回答4

0

縦に並べたカレンダーを印刷して, 縦横に並べたイメージを切り貼りで実際に作っては如何でしょう.
そして, 上から一行ずつに定規等を当てていけば, いつどの表示をすれば良いのかが見えてくると思います.

投稿2019/08/03 18:01

jimbe

総合スコア12545

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

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

0

if文は「if (式) 文」という構文で、式の値が 0 でなければ文を実行します。
if (k != 0) printf(" "); と同じです。
if (k > 0) printf(" "); と書いても構いません。
2番目以降の月を書くとき、左の月との間にスペースを置くということです。

投稿2019/08/05 01:20

kazuma-s

総合スコア8224

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

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

kokok

2019/08/05 01:33

理解できました。 ありがとうございます。
guest

0

ベストアンサー

display を、月を横にいくつ表示するかという意味に解釈しました。
最初に、12の約数だけ有効なコードを示しましたが、
5 や 7 などでもよいようにしてみました。

C

1//カレンダーを表示する 2void calendarprint(char calendar[N_MONTH][ROW_SIZE][N_WEEK], 3 int year, int display) 4{ 5 printf("%5d年\n", year); // 入力された年を表示 6 for (int month = JAN; month < N_MONTH; month += display) { 7 for (int m = month, k = 0; m < N_MONTH && k < display; k++, m++) 8 printf("%16d月 ", m + 1); 9 printf("\n\n"); 10 11 for (int m = month, k = 0; m < N_MONTH && k < display; k++, m++) { 12 if (k) printf(" "); 13 for (int i = 0; i <= SAT; i++) 14 printf(" %2s ", weeks[i]); //曜日の表示 15 } 16 printf("\n"); 17 18 for (int row = 0; row < ROW_SIZE; row++) { 19 for (int m = month, k = 0; m < N_MONTH && k < display; k++, m++) { 20 if (k) printf(" "); 21 for (int col = SUN; col <= SAT; col++) { 22 if (calendar[m][row][col] != 0) { // 日数が0でないなら 23 if (calendar[m][row][col] & HOLI_MARK) 24 printf("*"); 25 else if (calendar[m][row][col] & TRANS_MARK) 26 printf("+"); 27 else if (calendar[m][row][col] & BIRTH_MARK) 28 printf("&"); 29 else 30 printf(" "); 31 printf("%2d ", calendar[m][row][col] & 0x1F); 32 } 33 else // 日数が0なら 34 printf(" "); 35 } 36 } 37 printf("\n"); 38 } 39 printf("\n"); 40 } 41}

投稿2019/08/04 07:25

編集2019/08/04 12:49
kazuma-s

総合スコア8224

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

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

kokok

2019/08/05 00:25

ありがとうございます。 if (k) printf(" "); ここは何をやっているのでしょうか?
kazuma-s

2019/08/05 01:34

すみません。コメントを書いたつもりが回答に入ってしまったようです。
kokok

2019/08/05 01:44

いえいえ。 ありがとうございます。
guest

0

3ヶ月分を横に並べられるだけの1行ぶんのバッファを用意しといて、
3ヶ月のカレンダ文字列を生成、その1行づつを位置あわせのスペースを挟みながら横に3つ並べて出力する、ということですね。
位置合わせがちょっと難しいですが、まあ、がんばってください

投稿2019/08/02 07:46

y_waiwai

総合スコア87719

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問