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

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

ただいまの
回答率

88.23%

C言語 3次元配列にカレンダーの数値を入れたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 754

kokok

score 109

#pragma warning(disable: 4996)
#include<stdio.h>

#define ROW_SIZE 6  //カレンダーの行のサイズ

enum  M_LIST { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOW, DEC, N_MONTH };
enum W_LIST { SUN, MON, TUE, WED, THU, FRI, SAT, N_WEEK };
int  monthdays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //月の日数

//プロトタイプの宣言
int januaryoneday(int year);
int leapyear(int year);
int calendarmake(int  calendar[N_MONTH][ROW_SIZE][N_WEEK], int week , int  monthdays[]);




int main(void) {

    char* weeks[] = { "日","月","火","水","木","金","土" };

    int  calendar[N_MONTH][ROW_SIZE][N_WEEK];    // カレンダーの多次元配列

    int year;   //入力された西暦
    int month; //入力された月
    int day; //入力された日
    int week;  // //入力された西暦の1月1日の曜日
    int  judgment; //入力された値がうるう年だったかどうか
    int sumday; //    入力された西暦までの日数の合計
    int birthw; //入力された誕生日の曜日
    int monthdaysum = 0; // 入力された誕生日の月までの合計の日数

    printf("西暦を入力してください(入力された西暦の1月1日の曜日が表示されます)または、誕生日の西暦月日を入力してください(例:2019 01 01)生年月日の間はスペースを入れてください)");
    scanf("%d %d %d", &year, &month, &day);



    week = januaryoneday(year);    //入力された西暦の1月1日の曜日を取得

    printf("%s\n", weeks[week]);    //入力された西暦の1月1日の曜日を表示

    judgment = leapyear(year);       //うるう年の判定結果を取得


    monthdays[FEB] = (judgment == 0) ? 29 : 28;      // うるう年であれば2月を29日に変更



    sumday = ((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400);   //入力された西暦までの日数の合計

    for (int i = JAN; i < month - 1; i++) {  //入力された誕生日の月までの合計の日数

        monthdaysum += monthdays[i];


    }


    birthw = (sumday + monthdaysum + day) % 7;  //    入力された誕生日までの合計の日数 の曜日を取得

    printf("%s", weeks[birthw]);   //入力された誕生日の曜日を表示

    calendarmake(calendar[N_MONTH][ROW_SIZE][N_WEEK], week, monthdays);



    int c = calendarmake(calendar, week);   // カレンダーで表示された最後の曜日

    printf("%s\n", weeks[c]);

}



//入力された西暦の1月1日の曜日を返す
int januaryoneday(int year) {

    int sumday; // 入力された西暦までの累計日数
    int dayw; // 曜日計算

    sumday = ((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400); //入力された1月1日までの日数

    dayw = (sumday + 1) % 7;

    return dayw;
}


//入力された西暦がうるう年かの判定
int leapyear(int year) {

    int leap;

    leap = (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) ? 0 : -1;   //うるう年なら0を 違うなら-1 を

    return leap;

}

//カレンダーを作る
int calendarmake(int  calendar[N_MONTH][ROW_SIZE][N_WEEK], int week ) {

    int month;
    int col;
    int row;
    int day = 0;


    for (month = JAN; month < DEC; month++) {

        for (row = 0; row < ROW_SIZE; row++) {

            for (col = 0; col < N_WEEK; col++) {

                if (row == 0 && col < week) {

                    continue;
                }

                day++;

                calendar[month][row][col] = day;

                if (monthdays[month] == day) {

                    week = col;

                    day = 0;
                    break;
                }
            }
        }
    }

    return week;
}


//カレンダーを作る
int calendarmake(int  calendar[N_MONTH][ROW_SIZE][N_WEEK], int week )

で三次元配列に日にちを格納したいのですが、なかなか進まなかったのでアドバイス頂けると幸いです。

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

int calendarmake(int  calendar[N_MONTH][ROW_SIZE][N_WEEK], int week )

関数の中を書いてみました。
自分なりに書いてみたのですが、曜日が合わないです。
アドバイス頂けると助かります。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • thkana

    2019/07/31 21:48

    `int calendarmake(int calendar[N_MONTH][ROW_SIZE][N_WEEK], int week , int monthdays[]);`
    を呼び出すのに
    `calendarmake(calendar[N_MONTH][ROW_SIZE][N_WEEK], week, monthdays);`
    なんてのは...曜日が合わないとかそういう次元じゃないように思います。
    配列の扱いを再確認して下さい。

    コンパイラは少なくとも警告を出しているんじゃないかと思いますが、違いますか?

    キャンセル

  • jimbe

    2019/07/31 21:58

    修正中の行はコメント化するなどして, コンパイル・実行すれば再現出来る状態でご提示ください.
    「曜日が合わない」とは具体的に何年何月何日としたら何曜日になったのでしょうか.
    また, 単に曜日を出すだけであれば calendar[N_MONTH][ROW_SIZE][N_WEEK] は必要無いと思います.
    calendar[N_MONTH][ROW_SIZE][N_WEEK] はどのような内容でどのようにお使いのつもりでしょうか.

    キャンセル

  • 退会済みユーザー

    2019/08/01 00:30

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

0

年間カレンダー生成に関する部分のみです.
入力部も省略してyear固定にしています.

#include <stdio.h>
#include <memory.h>

#define N_ROW 6  //カレンダーの行のサイズ

enum M_LIST { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOW, DEC, N_MONTH };
enum W_LIST { SUN, MON, TUE, WED, THU, FRI, SAT, N_WEEK };
char *weeks[] = { "日","月","火","水","木","金","土" };
int  monthdays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //月の日数

//西暦の1月1日の曜日を返す
int calcWeekdayOfJanuaryOne(int year) {
  int sumday = ((year-1)*365) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400);
  return (sumday + 1) % 7;
}

//入力された西暦がうるう年かの判定. うるう年なら !0
int isLeapyear(int year) {
  return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}

//カレンダーを作る
void makeCalendar(int week, int calendar[N_MONTH][N_ROW][N_WEEK]) {
  memset(&calendar[0][0][0], 0, sizeof(calendar[0][0][0])*N_MONTH*N_ROW*N_WEEK);
  for(int month=JAN; month<N_MONTH; month++) {
    int *p = &calendar[month][0][week];
    for(int day=1; day<=monthdays[month]; day++) *p++ = day;
    week = (week + monthdays[month]) % 7;
  }
}

void printCalendar(int year, int calendar[N_MONTH][N_ROW][N_WEEK]) {
  printf("%d年\n", year);
  for(int month=JAN; month<N_MONTH; month++) {
    printf("         %-2d月\n", month+1);
    for(int weekday=0; weekday<N_WEEK; weekday++) {
      printf(" %2s", weeks[weekday]);
    }
    printf("\n");
    for(int row=0; row<N_ROW; row++) {
      for(int weekday=0; weekday<N_WEEK; weekday++) {
        if(calendar[month][row][weekday] == 0) {
          printf("   ");
        } else {
          printf(" %2d", calendar[month][row][weekday]);
        }
      }
      printf("\n");
    }
  }
}

int main() {
  int calendar[N_MONTH][N_ROW][N_WEEK];
  int year = 2019;

  // うるう年であれば2月を29日に変更
  monthdays[FEB] = isLeapyear(year) ? 29 : 28;

  int weekday = calcWeekdayOfJanuaryOne(year);
  makeCalendar(weekday, calendar);
  printCalendar(year, calendar);

  return 0;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る