🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

8回答

1663閲覧

コードを改良して1年間のカレンダーを作りたい(曜日と日付の並びをそろえたい)

kkk69

総合スコア2

C

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

0グッド

2クリップ

投稿2021/01/22 03:54

編集2021/01/23 07:16

粗末な質問の仕方ですみませんでした。

下のコードを改良して、縦に3か月横に4か月分の1年間分のカレンダーを作りたいです。
現在実行すると

このように曜日か一つずつずれてしまいます。

どうすれば曜日と日付をそろえることができますか
言語はC言語です。

よろしくお願いします。

#include <stdio.h> #include <string.h> #define YEAR 2021 #define MONTH 1 #define WEEKof1 5 #define MON_WIDTH 30 enum { ROW = 3, COL = (12/ROW) }; int dayOfMonth[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int leapYear(int year) { return (year % 4) == 0; } void getCalender(char s[8][MON_WIDTH], int y, int m, int wof) { int cal[6][7]; int dom = dayOfMonth[leapYear(y)][m - 1]; int i, d; for (i = 0; i < wof; i++) cal[0][i] = 0; for (d = 0; d < dom; d++) { int row = (wof + d) / 7; int col = (wof + d) % 7; cal[row][col] = d + 1; } for (i = wof + dom; i < 7 * 6; i++) { int row = i / 7; int col = i % 7; cal[row][col] = 0; } sprintf(s[0], " %4d年%2d月", y, m); sprintf(s[1], " 日 月 火 水 木 金 土"); for (i = 0; i < 6; i++) { s[i + 2][0] = '\0'; char tmp[10]; for (d = 0; d < 7; d++) { if (cal[i][d] == 0) sprintf(tmp, " "); else sprintf(tmp, " %2d", cal[i][d]); strcat(s[i + 2], tmp); } } } int getWeekOf1(int year,int month,int this_year_wof1) { int m; int serial_day = 0; int wof1; for (m = 1; m < month;m++){ serial_day += dayOfMonth[leapYear(year)][m-1]; } wof1 = (serial_day + this_year_wof1) % 7; return wof1; } void main(void) { char calender[12][8][MON_WIDTH]; int i,row,col; int m; int wof1; for (m = 1; m <= 12; m++){ wof1 = getWeekOf1(YEAR,m,WEEKof1); getCalender(calender[m-1], YEAR, m, wof1); } for (row = 0;row < ROW;row++){ for (int i = 0; i < 8; i++) { for (col = 0; col < COL; col++){ printf("%-24s",calender[row*COL+col][i]); } printf("\n"); } } }

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

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

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

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

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

y_waiwai

2021/01/22 04:03

提示のコードではどうなるんでしょうか。 そして、それを具体的にどうしたいんでしょう。そこらへんを詳しく解説しましょう また、このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
gentaro

2021/01/22 04:06

「どこをどのように書き換えて、追記すればいいか」を考えるのはあなたの責務であって、あなたが考えて実行した結果うまく行かない点を質問しようや。
guest

回答8

0

前に提示したソースはShift-JIS前提でした。
文字コードがutf-8の場合、漢字を含めてたデータを完全にきちんとそろえて出力するのは無理なようです。
(私が知らないだけかも知れませんが・・・)
以下は、いろいろ調整してそろえようと努力した結果です。

C

1#include <stdio.h> 2#include <string.h> 3#define YEAR 2021 4#define MONTH 1 5#define WEEKof1 5 6#define MON_WIDTH 30 7enum { ROW = 3, COL = (12/ROW) }; 8 9 10int dayOfMonth[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 11{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 12}; 13 14int leapYear(int year) 15{ 16 return (year % 4) == 0; 17} 18 19void getCalender(char s[8][MON_WIDTH], int y, int m, int wof) 20{ 21 int cal[6][7]; 22 int dom = dayOfMonth[leapYear(y)][m - 1]; 23 int i, d; 24 25 26 for (i = 0; i < wof; i++) 27 cal[0][i] = 0; 28 for (d = 0; d < dom; d++) { 29 int row = (wof + d) / 7; 30 int col = (wof + d) % 7; 31 cal[row][col] = d + 1; 32 } 33 for (i = wof + dom; i < 7 * 6; i++) { 34 int row = i / 7; 35 int col = i % 7; 36 cal[row][col] = 0; 37 } 38 39 40 sprintf(s[0], " %4d年%2d月 ", y, m); 41 sprintf(s[1], " 日 月 火 水 木 金 土 "); 42 for (i = 0; i < 6; i++) { 43 s[i + 2][0] = '\0'; 44 char tmp[10]; 45 for (d = 0; d < 7; d++) { 46 if (cal[i][d] == 0) 47 sprintf(tmp, " "); 48 else 49 sprintf(tmp, " %2d", cal[i][d]); 50 strcat(s[i + 2], tmp); 51 } 52 } 53} 54//指定年月の1日の週の番号を求める(日:0、月:1、...、土:6) 55//year:年 56//month:月 57//this_year_wof1:当該年の1月1日の週の番号 58int getWeekOf1(int year,int month,int this_year_wof1) 59{ 60 int m; 61 int serial_day = 0; 62 int wof1; 63 for (m = 1; m < month;m++){ 64 serial_day += dayOfMonth[leapYear(year)][m-1]; 65 } 66 wof1 = (serial_day + this_year_wof1) % 7; 67 return wof1; 68} 69void main(void) 70{ 71 char calender[12][8][MON_WIDTH]; 72 int i,row,col; 73 int m; 74 int wof1; 75 for (m = 1; m <= 12; m++){ 76 wof1 = getWeekOf1(YEAR,m,WEEKof1); 77 getCalender(calender[m-1], YEAR, m, wof1); 78 } 79 for (row = 0;row < ROW;row++){ 80 for (int i = 0; i < 8; i++) { 81 for (col = 0; col < COL; col++){ 82 printf("%s ",calender[row*COL+col][i]); 83 } 84 printf("\n"); 85 } 86 } 87} 88

実行結果

イメージ説明

①getWeekOf1ですが、指定された年月に対応するの1日の週番号を求めています。
2021年1月なら5
2021年2月なら1
2021年3月なら1
2021年4月なら4、以下同様
を返します。
この値は、getCalenderのwofへ渡す値として使用されます。
この値をどのようにして算出するかということですが、
1案:if 文で判断して直接返す。
2案:1月1日は、#define WEEKof1 5 で与えられているので、それを利用して算出する。
のどちらかになります。
1案なら
if month == 1 return 5;
if month == 2 return 1;
if month == 3 return 1;
if month == 4 return 4;
のように書きます。
この案の利点は、深く考える必要がないということです。
欠点は、来年のカレンダーを作る場合は、全て書き換えないといけない、ということです。
今回は2案を採用しています。
2案の場合は、来年になった場合、#define WEEKof1 5のみを書き換えれば、済みます。
算出方法は、
2021年1月なら、WEEKof1の値を返す。
2021年2月なら、WEEKof1に1月分の日付を加算した値(31)を7で割った余りを返す。(5+31)%7=1
2021年3月なら、WEEKof1に2月分までの日付を加算した値(31+28)を7で割った余りを返す。(5+31+28)%7=1
以降同様です。

②mainについて
一か月分のカレンダーは、char calender[8][MON_WIDTH];を確保し、
getCalender(calender, YEAR, 1, 5);
で作成しています。
つまり、getCalenderに作成したい年、月、及び週番号を与えると、calenderにその内容が設定されて
返ってきます。そして、それを印字すれば、完了です。
縦に1年分のカレンダーを印字する場合は、これを12回繰り返せば、それが実現できます。
しかしながら、横に4列の場合は、1行を印字するときに、横に4か月ぶんのカレンダーの内容を
一度に印字しないといけません。(一度、改行してしまうと、前の行に戻ることはできない為)
その為、12か月分のカレンダー領域を確保し、12月分のカレンダーをまず作成します。
領域はchar calender[12][8][MON_WIDTH];のようになります。
for (m = 1; m <= 12; m++){のループの部分で、12月分のカレンダーを作成しています。

次にカレンダーの印字です。
for (row = 0;row < ROW;row++){の部分で、以下の処理(4か月分の印字)3回繰り返します。
for (int i = 0; i < 8; i++) {の部分で、4か月分のカレンダーの1行目から8行目の印字を繰り返します。
for (col = 0; col < COL; col++){の部分で各月の印字(4か月分の各月)を4回繰り返します。
4か月分の印字が終了後、改行を印字します。

投稿2021/01/23 09:52

編集2021/01/24 00:23
tatsu99

総合スコア5493

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

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

kkk69

2021/01/23 10:53

UTF-8ですがこの通りで実行できました。 int getWeekOf1からmainの最後までの処理の内容の解説を教えてください。
tatsu99

2021/01/24 00:23

回答欄に追記しました。
kkk69

2021/01/24 10:41

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

0

質問のコードを改良したわけではなく、全く違ったコードを書いたので回答とは
言えませんが、まあ、こんなふうにも書けますよ、ということでお許しを。

C

1#include <stdio.h> 2 3enum { ROW = 4, COL = 3 }; 4 5int dow(int y, int m, int d) // day of the week 6{ 7 return y-=m<3,(y+y/4-y/100+y/400+".\0\3\2\5\0\3\5\1\4\6\2\4"[m]+d)%7; 8} 9 10void set(int a[6][7], int y, int m) 11{ 12 int z = 28+(m==2?y%4==0&&(y%100||y%400==0):".\3\0\3\2\3\2\3\3\2\3\2\3"[m]); 13 for (int j = dow(y, m, 1), d = 0, i = 0; i < 6; i++, j = 0) 14 for (; j < 7; a[i][j++] = d) 15 if (++d > z) return; 16} 17 18void print(int a[COL][6][7], int y, int m) 19{ 20 for (int i = 0; i < COL; i++) printf("%10d年%2d月%8s", y, m + i, ""); 21 putchar('\n'); 22 for (int i = 0; i < COL; i++) printf(" 日 月 火 水 木 金 土 "); 23 putchar('\n'); 24 for (int j = 0; j < 6; j++, putchar('\n')) 25 for (int i = 0; i < COL; i++, printf(" ")) 26 for (int k = 0; k < 7; k++) 27 printf(a[i][j][k] ? "%3d" : " ", a[i][j][k]); 28 putchar('\n'); 29} 30 31void cal(int y) 32{ 33 for (int m = 1; m < 12; m += COL) { 34 int a[COL][6][7] = { 0 }; 35 for (int i = 0; i < COL; i++) set(a[i], y, m + i); 36 print(a, y, m); 37 } 38} 39 40int main(void) 41{ 42 for (int y; printf("year> "), scanf("%d", &y) == 1; cal(y)) ; 43}

追記
質問が最初と変わっていますね。
新たな質問の場合、元の質問を残したうえで、追記しましょう。

printf("%-24s" の 24 はバイト数です。
文字コードが Shift-JIS の場合は、漢字は 2バイトで表示幅も2桁ですが、
文字コードが UTF-8 の場合は、漢字は 3バイトなのでずれます。
次のようにすればよいでしょう。

diff

1- sprintf(s[0], " %4d年%2d月", y, m); 2+ sprintf(s[0], " %4d年%2d月 ", y, m); 3 4- printf("%-24s",calender[row*COL+col][i]); 5+ printf("%s ",calender[row*COL+col][i]);

投稿2021/01/22 17:27

編集2021/01/23 08:10
kazuma-s

総合スコア8224

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

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

tatsu99

2021/01/23 01:14

これは、素晴らしいですね。 質問者の方がこれを利用される場合は、 enum { ROW = 4, COL = 3 };を enum { ROW = 3, COL = 4 };に 修正すれば望んだ結果になります。
kkk69

2021/01/23 08:53

すいません。次から追記するようにします。
guest

0

c.c

c

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> // atoi() 4 5int dayOfMonth[2][12] = { 6 {31,28,31,30,31,30,31,31,30,31,30,31}, 7 {31,29,31,30,31,30,31,31,30,31,30,31} 8}; 9 10char *heads[2] = { 11 " %4d年%2d月 ", 12 " 日 月 火 水 木 金 土" 13}; 14 15int leapYear(int year) { 16 return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; 17} 18 19int weekOfDay(int y, int m, int d) { 20 if (m < 3) { 21 y--; 22 m += 12; 23 } 24 int days = 365 * y + y / 4 - y / 100 + y / 400 + 306 * (m + 1) / 10 + d - 428; 25 return days % 7; // 0: 日曜日, 1: 月曜日, ... 26} 27 28void getCalendar(int cal[], int year, int month) { 29 int first_day = weekOfDay(year, month, 1); 30 int days; 31 if (leapYear(year)) { 32 days = dayOfMonth[1][month - 1]; 33 } else { 34 days = dayOfMonth[0][month - 1]; 35 } 36 37 for (int i = 0; i < 42; i++) { 38 cal[i] = 0; 39 } 40 for (int d = 1; d <= days; d++) { 41 cal[first_day - 1 + d] = d; 42 } 43} 44 45void showCalendars(int num, int * cals[], int years[], int months[]) { 46 for (int c = 0; c < num; c++) { 47 printf(heads[0], years[c], months[c]); 48 printf(" "); 49 } 50 printf("\n"); 51 for (int c = 0; c < num; c++) { 52 printf("%s", heads[1]); 53 printf(" "); 54 } 55 printf("\n"); 56 57 for (int y = 0; y < 6; y++) { 58 for (int c = 0; c < num; c++) { 59 for (int x = 0; x < 7; x++) { 60 int v = cals[c][y * 7 + x]; 61 if (v) { 62 printf("%3d", v); 63 } else { 64 printf(" "); 65 } 66 } 67 printf(" "); 68 } 69 printf("\n"); 70 } 71 printf("\n"); 72} 73 74void make_calendar(int year) { 75 int calendars[12][42]; 76 for (int i = 1; i <= 12; i++) { 77 getCalendar(calendars[i - 1], year, i); 78 } 79 int years[] = {0, 0, 0, 0, 0 ,0, 0, 0 ,0 , 0, 0, 0 }; 80 int months[] = {0, 0, 0, 0, 0 ,0, 0, 0 ,0 , 0, 0, 0 }; 81 int * cals[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 82 83 int cols = 3; // 横に並べる月の個数 84 int rows = 12 / cols; // 段数 85 for (int y = 0; y < rows; y++) { 86 for (int c = 0; c < cols; c++) { 87 years[c] = year; 88 months[c] = y * cols + c + 1; 89 cals[c] = calendars[months[c] - 1]; 90 } 91 showCalendars(3, cals, years, months); 92 } 93} 94 95int main(int argc, char ** argv) { 96 int year = 0; 97 if (argc == 1) { 98 year = 2021; 99 } else if (argc == 2) { 100 year = atoi(argv[1]); 101 } else { 102 printf(" usage %s year\n", argv[0]); 103 return -1; 104 } 105 106 make_calendar(year); 107 return 0; 108} 109

実行例
イメージ説明

参考情報

  • 曜日計算

https://www.kkaneko.jp/cc/program/date.html

投稿2021/01/23 09:50

katoy

総合スコア22324

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

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

0

ベストアンサー

縦3列、横4列の1年分のカレンダーです。
縦横の調整はkazuma-sさんのプログラムを参考にさせていただきました。

C

1#include <stdio.h> 2#include <string.h> 3#define YEAR 2021 4#define MONTH 1 5#define WEEKof1 5 6#define MON_WIDTH 30 7enum { ROW = 3, COL = (12/ROW) }; 8 9int dayOfMonth[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 10{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 11}; 12 13int leapYear(int year) 14{ 15 return (year % 4) == 0; 16} 17 18void getCalender(char s[8][MON_WIDTH], int y, int m, int wof) 19{ 20 int cal[6][7]; 21 int dom = dayOfMonth[leapYear(y)][m - 1]; 22 int i, d; 23 24 25 for (i = 0; i < wof; i++) 26 cal[0][i] = 0; 27 for (d = 0; d < dom; d++) { 28 int row = (wof + d) / 7; 29 int col = (wof + d) % 7; 30 cal[row][col] = d + 1; 31 } 32 for (i = wof + dom; i < 7 * 6; i++) { 33 int row = i / 7; 34 int col = i % 7; 35 cal[row][col] = 0; 36 } 37 38 39 sprintf(s[0], " %4d年%2d月", y, m); 40 sprintf(s[1], " 日 月 火 水 木 金 土"); 41 for (i = 0; i < 6; i++) { 42 s[i + 2][0] = '\0'; 43 char tmp[10]; 44 for (d = 0; d < 7; d++) { 45 if (cal[i][d] == 0) 46 sprintf(tmp, " "); 47 else 48 sprintf(tmp, " %2d", cal[i][d]); 49 strcat(s[i + 2], tmp); 50 } 51 } 52} 53//指定年月の1日の週の番号を求める(日:0、月:1、...、土:6) 54//year:年 55//month:月 56//this_year_wof1:当該年の1月1日の週の番号 57int getWeekOf1(int year,int month,int this_year_wof1) 58{ 59 int m; 60 int serial_day = 0; 61 int wof1; 62 for (m = 1; m < month;m++){ 63 serial_day += dayOfMonth[leapYear(year)][m-1]; 64 } 65 wof1 = (serial_day + this_year_wof1) % 7; 66 return wof1; 67} 68void main(void) 69{ 70 char calender[12][8][MON_WIDTH]; 71 int i,row,col; 72 int m; 73 int wof1; 74 for (m = 1; m <= 12; m++){ 75 wof1 = getWeekOf1(YEAR,m,WEEKof1); 76 getCalender(calender[m-1], YEAR, m, wof1); 77 } 78 for (row = 0;row < ROW;row++){ 79 for (int i = 0; i < 8; i++) { 80 for (col = 0; col < COL; col++){ 81 printf("%-24s",calender[row*COL+col][i]); 82 } 83 printf("\n"); 84 } 85 } 86} 87

実行結果
イメージ説明

投稿2021/01/23 02:56

編集2021/01/23 03:05
tatsu99

総合スコア5493

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

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

kkk69

2021/01/23 06:39

getWeekOfからmain メソッドの中身の大まかな処理の内容とどうしてこの書き方をするのか解説をお願いします。
guest

0

縦に1年分のカレンダーを作るようにしました。
変えたのはmainとgetWeekOf1(追加)です。ほかは変えていません。
後は、これを縦に3か月横に4か月分の1年間分のカレンダーに変えるだけです。

C

1#include <stdio.h> 2#include <string.h> 3#define YEAR 2021 4#define MONTH 1 5#define WEEKof1 5 6#define MON_WIDTH 30 7 8 9int dayOfMonth[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 10{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 11}; 12 13int leapYear(int year) 14{ 15 return (year % 4) == 0; 16} 17 18void getCalender(char s[8][MON_WIDTH], int y, int m, int wof) 19{ 20 int cal[6][7]; 21 int dom = dayOfMonth[leapYear(y)][m - 1]; 22 int i, d; 23 24 25 for (i = 0; i < wof; i++) 26 cal[0][i] = 0; 27 for (d = 0; d < dom; d++) { 28 int row = (wof + d) / 7; 29 int col = (wof + d) % 7; 30 cal[row][col] = d + 1; 31 } 32 for (i = wof + dom; i < 7 * 6; i++) { 33 int row = i / 7; 34 int col = i % 7; 35 cal[row][col] = 0; 36 } 37 38 39 sprintf(s[0], " %4d年%2d月", y, m); 40 sprintf(s[1], " 日 月 火 水 木 金 土"); 41 for (i = 0; i < 6; i++) { 42 s[i + 2][0] = '\0'; 43 char tmp[10]; 44 for (d = 0; d < 7; d++) { 45 if (cal[i][d] == 0) 46 sprintf(tmp, " "); 47 else 48 sprintf(tmp, " %2d", cal[i][d]); 49 strcat(s[i + 2], tmp); 50 } 51 } 52} 53//指定年月の1日の週の番号を求める(日:0、月:1、...、土:6) 54//year:年 55//month:月 56//this_year_wof1:当該年の1月1日の週の番号 57int getWeekOf1(int year,int month,int this_year_wof1) 58{ 59 int m; 60 int serial_day = 0; 61 int wof1; 62 for (m = 1; m < month;m++){ 63 serial_day += dayOfMonth[leapYear(year)][m-1]; 64 } 65 wof1 = (serial_day + this_year_wof1) % 7; 66 return wof1; 67} 68void main(void) 69{ 70 char calender[8][MON_WIDTH]; 71 int i; 72 int m; 73 int wof1; 74 for (m = 1; m <= 12; m++){ 75 wof1 = getWeekOf1(YEAR,m,WEEKof1); 76 getCalender(calender, YEAR, m, wof1); 77 for (int i = 0; i < 8; i++) { 78 puts(calender[i]); 79 } 80 } 81} 82

投稿2021/01/22 12:35

tatsu99

総合スコア5493

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

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

kkk69

2021/01/22 13:33

ありがとうございます 12か月分縦に表示することができました。 縦列と横列の変更はどのようにしたらよいのですか?
tatsu99

2021/01/23 03:06

新たに回答しました。
guest

0

とりあえず、不具合だけは修正しました。

C

1#include <stdio.h> 2#include <string.h> 3#define YEAR 2021 4#define MONTH 1 5#define WEEKof1 5 6#define MON_WIDTH 30 7 8 9int dayOfMonth[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 10{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 11}; 12 13int leapYear(int year) 14{ 15 return (year % 4) == 0; 16} 17 18void getCalender(char s[8][MON_WIDTH], int y, int m, int wof) 19{ 20 int cal[6][7]; 21 int dom = dayOfMonth[leapYear(y)][m - 1]; 22 int i, d; 23 24 25 for (i = 0; i < wof; i++) 26 cal[0][i] = 0; 27 for (d = 0; d < dom; d++) { 28 int row = (wof + d) / 7; 29 int col = (wof + d) % 7; 30 cal[row][col] = d + 1; 31 } 32 for (i = wof + dom; i < 7 * 6; i++) { 33 int row = i / 7; 34 int col = i % 7; 35 cal[row][col] = 0; 36 } 37 38 39 sprintf(s[0], " %4d年%2d月", y, m); 40 sprintf(s[1], " 日 月 火 水 木 金 土"); 41 for (i = 0; i < 6; i++) { 42 s[i + 2][0] = '\0'; 43 char tmp[10]; 44 for (d = 0; d < 7; d++) { 45 if (cal[i][d] == 0) 46 sprintf(tmp, " "); 47 else 48 sprintf(tmp, " %2d", cal[i][d]); 49 strcat(s[i + 2], tmp); 50 } 51 } 52} 53 54void main(void) 55{ 56 char calender[8][MON_WIDTH]; 57 getCalender(calender, YEAR, MONTH, WEEKof1); 58 for (int i = 0; i < 8; i++) { 59 puts(calender[i]); 60 } 61} 62

実行結果
イメージ説明

修正個所は以下の通り

diff

1 % diff goo1.org.c goo1.c 218c18 3< void getCalender(char s[7][MON_WIDTH], int y, int m, int wof) 4--- 5> void getCalender(char s[8][MON_WIDTH], int y, int m, int wof) 620c20 7< int cal[5][7]; 8--- 9> int cal[6][7]; 1032c32 11< for (i = wof + dom; i < 7 * 5; i++) { 12--- 13> for (i = wof + dom; i < 7 * 6; i++) { 1441c41 15< for (i = 0; i < 5; i++) { 16--- 17> for (i = 0; i < 6; i++) { 1856c56 19< char calender[7][MON_WIDTH]; 20--- 21> char calender[8][MON_WIDTH]; 2258c58 23< for (int i = 0; i < 7; i++) { 24--- 25> for (int i = 0; i < 8; i++) { 26

投稿2021/01/22 12:08

tatsu99

総合スコア5493

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

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

thkana

2021/01/24 01:14

別解ということならともかく、「修正しました」で別回答にするのはいかがなものか、と。
tatsu99

2021/01/24 01:25

前の回答を更新したほうが、良かったですかね。以降、注意します。ご指摘ありがとう御座いました。
guest

0

提示されたソースを多少修正して実行してみました。
//追加のコメントがいれてあります。
実行結果をみればわかりますが、
1日、2日に位置はずれていません。
しかしながら、31日の日付がありません。
これは致命的です。まず、これを修正するのが先決かと思います。

C

1#include <stdio.h> //追加 2#include <string.h> 3#define YEAR 2021 4#define MONTH 1 5#define WEEKof1 5 6#define MON_WIDTH 30 7 8 9int dayOfMonth[2][12] = {{31,28,31,30,31,30,31,31,30,31,30,31}, 10 {31,29,31,30,31,30,31,31,30,31,30,31}}; 11 12int leapYear(int year) { 13 return (year % 4)==0; 14} 15 16void getCalender(char s[7][MON_WIDTH],int y, int m, int wof) { 17 int cal[5][7]; 18 int dom = dayOfMonth[leapYear(y)][m-1]; 19 int i,d; 20 21 22 for(i=0;i < wof;i++) cal[0][i] = 0; 23 for(d=0;d < dom; d++) { 24 int row = (wof+d) / 7; 25 int col = (wof+d) % 7; 26 cal[row][col] = d+1; 27 } 28 for(i=wof+dom;i < 7*5; i++) { 29 int row = i / 7; 30 int col = i % 7; 31 cal[row][col] = 0; 32 } 33 34 35 sprintf(s[0]," %4d年%2d月",y,m); 36 sprintf(s[1]," 日 月 火 水 木 金 土"); 37 for(i = 0; i < 5; i++) { 38 s[i+2][0] = '\0'; 39 char tmp[10]; 40 for(d = 0; d < 7; d++) { 41 if(cal[i][d] == 0) sprintf(tmp, " "); 42 else sprintf(tmp," %2d",cal[i][d]); 43 strcat(s[i+2],tmp); 44 } 45 } 46} 47 48void main(void) { 49 char calender[7][MON_WIDTH]; 50 getCalender(calender,YEAR,MONTH,WEEKof1); 51 for(int i=0; i< 7; i++) { 52 puts(calender[i]); 53 } 54} //追加 55

実行結果
イメージ説明

投稿2021/01/22 09:25

tatsu99

総合スコア5493

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

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

kkk69

2021/01/22 10:38

コメントの追加の部分を編集しました。 この部分をどこか書き加えると31日が表示されると思うのですが どう書き加えるといいかわかりません。 ``` void getCalender(char s[7][MON_WIDTH],int y, int m, int wof) { int cal[5][7]; int dom = dayOfMonth[leapYear(y)][m-1]; int i,d; for(i=0;i < wof;i++) cal[0][i] = 0; for(d=0;d < dom; d++) { int row = (wof+d) / 7; int col = (wof+d) % 7; cal[row][col] = d+1; } for(i=wof+dom;i < 7*5; i++) { int row = i / 7; int col = i % 7; cal[row][col] = 0; } ```
guest

0

現在のカレンダ出力を、ループさせて月を1から12まで繰り返せばよろしい

まずは単純にループさせてみたらどういう出力になります?

投稿2021/01/22 05:50

y_waiwai

総合スコア88038

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

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

kkk69

2021/01/22 10:18

for(int t=0; t<12; t++)という一文をmainメソッドの一行目に足してみました。 これで12回繰り返せました。 結果は1月のカレンダーが縦に12個並びました。
y_waiwai

2021/01/22 10:25

月を1から12まで変えようよ t+1 を与えてやればよろしい
kkk69

2021/01/22 10:50

t+1をどこに与えてやれば月を変化させることができますか 何か所か書き足してみたのですが実行結果に変化がなくて...
y_waiwai

2021/01/22 11:03

ああ、その前に年と月を引数にとってカレンダを出す関数作るのが先やね それを作ろう
kkk69

2021/01/22 11:34

月は int Manth [] = {1,2,3,4,5,6,7,8,9,10,11,12}; 年は int leapYear(int year)     return (year % 4)==0; という風に書いてみたんですけどこれを使ってどうやってカレンダーをだす関数を作ったらいいですか
y_waiwai

2021/01/22 11:37

その年のその月の1日が何曜日かわかればカレンダーはできるでしょ。 ついでに、2月の場合はうるう年かどうかを算出すればよろしい
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問