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

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

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

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

Q&A

3回答

2732閲覧

c言語でカレンダーの表示をしたい

retoruto1257

総合スコア7

C

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

0グッド

0クリップ

投稿2018/03/07 08:48

現在C言語で西暦と月を入力することで、その一か月分のカレンダーを作っています。
日付と曜日の出力をさせることが出来たのですが、
この日付けの横に祝日や休日のマークを出るようにしたいのですがどのように書けばいいのでしょうか。
よろしくお願いします。

C言語

1#include <stdio.h> 2#include <stdlib.h> 3 4int leap_year(int year); /*うるう年*/ 5int day_month(int year,int month); /*月と日*/ 6void print_calendar(int year,int month); /*カレンダーの表示*/ 7int week_day(int year,int month,int day); /*週と曜日*/ 8int holi_day(int year,int month); /*祝日*/ 9 10 11/*入力部分*/ 12int main(void){ 13 int year; /*年*/ 14 int month; /*月*/ 15 16 char year_num[9999]; /*西暦の入力*/ 17 printf("西暦を入力してください(1~9999)\n"); 18 printf("year -->"); 19 fgets(year_num, 16, stdin); 20 year=atoi(year_num); 21 22 if(1>year || year>9999){ 23 printf("エラーです入力しなおしてください\n"); 24 }else{ 25 printf("入力された西暦は%dです\n",year); 26 } 27 28 char month_num[12]; /*月の入力*/ 29 printf("月を入力してください(1~12)\n"); 30 printf("month -->"); 31 fgets(month_num, 16, stdin); 32 month=atoi(month_num); 33 34 if(1>month || month>12){ 35 printf("エラーです入力しなおしてください\n"); 36 }else{ 37 printf("入力された月は%dです\n",month); 38 } 39 print_calendar(year, month); /*カレンダーの表示*/ 40 41 return 0; 42} 43 44 45/*** カレンダーの表示 ***/ 46/* (仮引数)y:西暦年 m:月 (返却値)なし */ 47void print_calendar(int year, int month) 48{ 49 int day_count, first_day, last_day; 50 51 first_day = week_day(year, month, 1); /* 1日の曜日を求める */ 52 last_day = day_month(year, month); /* 月の最終日を求める */ 53 54 printf(" ** %d年%d月 **\n", year, month); 55 printf(" 日 月 火 水 木 金 土\n"); 56 printf("---------------------\n"); 57 58 for (day_count = 1; day_count <= first_day; day_count++) { /* 1日まで空白で埋める */ 59 printf(" "); 60 } 61 for (day_count = 1; day_count <= last_day; day_count++) { /* 最終日まで表示する */ 62 printf(" %2d", day_count); 63 if ( (day_count + first_day) % 7 == 0) { /* 土曜日で改行する */ 64 putchar('\n'); 65 } 66 } 67} 68 69/*月最後の日*/ 70int day_month(int year,int month){ 71 int day =0; 72 int last_days[]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 73 /*月の最後の日*/ 74 if(month == 2) { 75 day = last_days[month-1] + leap_year(year); 76 } /*うるう年なら+1される*/ 77 else if (month >= 1 && month <= 12) { 78 day = last_days[month - 1]; /*2月以外はリスト通り*/ 79 } 80 return day; 81} 82/*月初めの曜日*/ 83int week_day(int year,int month,int day){ 84 if(month == 1) { 85 year = year - 1; 86 month = 13; 87 } /*公式を使うため1月を13月、2月を14月として扱う*/ 88 else if(month == 2) { 89 year = year - 1; 90 month = 14; 91 } 92 /*ツェラーの公式*/ 93 return (5 * year / 4 - year / 100 + year / 400 + (26 * month + 16) / 10 + day) % 7; 94} 95 96 97int leap_year(int year){ 98 int leap_years = 0; 99 100 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) { 101 leap_years = 1; 102 } 103 return leap_years; 104} 105 106 107int holi_cheek(int year ,int month ,int day){ /*祝日の選定*/ 108 int date = (5 * year / 4 - year / 100 + year / 400 + (26 * month + 16) / 10 + 1) % 7; 109 /*曜日を調べる*/ 110 /*==============================================*/ 111 /* 休日判定関数 */ 112 /* ・動 作 :休日判定を行い,マークを返します。*/ 113 /* ・仮引数 :年, 月, 日, 曜日 */ 114 /* ・戻り値 :次のいずれか1文字。 */ 115 /* :@:日曜, *:土曜, :平日 */ 116 /* :#:祝日, $:休日, &:振替 */ 117 /*==============================================*/ 118

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

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

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

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

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

ttyp03

2018/03/08 00:26

マークの出力方法がわからない?判定方法(holi_check関数の中身)がわからない?どちらですか?質問は明確にしましょう。
retoruto1257

2018/03/08 02:47

コメントありがとうございます。 正直マークの出力方法と判定方法の両方分かりません。
guest

回答3

0

土日は曜日が分かっていれば出力できますが、問題は祝日、そして振替休日です。
日本の祝日には3種類あります。
0. ○月×日、と、月日が固定されているもの(元日、こどもの日など)
0. ○月の第×月曜日、と、月と週が指定されているもの(ハッピーマンデー。成人の日など)
0. 官報あるいは特別立法で決定されるもの(春分の日・秋分の日、即位の日の祝日など)

このうち1,2は条件をデータ化して持っていればどうにかなりますが、3. だけは「何年何月何日」の形でデータを持つしかありません。(春分の日・秋分の日は閏年かどうかで概ね固定できますが、正確ではありません)
振替休日は、ある休日が日曜に該当した場合、その次に来る「平日」を振替休日にする、という処理になります(昔はその次の日、だったので、その次の日が休日の場合は振替休日がなくなっていました)。
ですのである日だけからはその日が振替休日に該当するかどうか分かりません(前日以前へ遡ってチェックする必要がある)
休日判定で「祝日かつ日曜日」を返すようにして、その結果をメインのループで保持(振替休日があるフラグ)&休日判定に渡して、「平日だけど振替休日があるならば、その日が振替休日」という形に処理する感じでしょうか。

投稿2018/03/07 09:00

tacsheaven

総合スコア13703

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

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

tacsheaven

2018/03/07 09:28 編集

おっと、もう一つパターンがありました。 4. 祝日と祝日に挟まれた一日は、休日とする 秋分の日が9月の第3水曜日になる場合、敬老の日(9月の第3月曜日)との兼ね合いで、3連休(土日を含めれば5連休)になる可能性があります。2009年がこれでした。次にこれになるのは2026年の可能性が高いのだとか。 来年、今上陛下の退位と皇太子殿下の即位で5月1日を祝日とする案が出ていますが、これが実現すると4月30日と5月2日も休日になるため、4/29~5/6 の8連休(5/5が日曜日のため5/6が振替休日)が出現します。土日が休みなら4/27 からの10連休ですね。 ※昔は5月4日がこれによる「休日」でした
guest

0

質問外の内容ですが、ユリウス暦からグレゴリオ暦への改暦の扱いも結構面倒です。

投稿2018/03/07 13:48

shsh_

総合スコア113

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

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

0

%cで1文字出力できるので、以下のような感じで日付の左側にマークを表示することができます。
またholi_checkでは曜日の判定が必要なようなのでfirst_dayも渡してあげるように修正したほうがよいです。

C

1 // 略 2 for (day_count = 1; day_count <= last_day; day_count++) { /* 最終日まで表示する */ 3 char holi_mark = holi_cheek( year, month, day_count); 4 printf("%c%2d", holi_mark, day_count); 5 if ( (day_count + first_day) % 7 == 0) { /* 土曜日で改行する */ 6 putchar('\n'); 7 } 8 } 9 10// 略 11int holi_cheek(int year ,int month ,int day){ 12 // 略 13 if(日曜) return '@';

具体的な判定については非常に面倒そうなので参考ページの提示にとどめます。
日本の祝祭日を計算してカレンダ-に表示するアプリサンプル

各自実装するのは無駄なので、疑似コードでいいからお国の機関が作って公開してほしい…

投稿2018/03/07 08:57

編集2018/03/07 09:38
can110

総合スコア38233

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問