カレンダーのプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kikku
記事: 2
登録日時: 10年前

カレンダーのプログラム

#1

投稿記事 by kikku » 10年前

初学者のものです。
表示する年月の範囲を読み込んで、横方向に3か月分のカレンダーを並べて表示するプログラムを作りました。
しかし実行してみたところ、12月のカレンダーだけが表示されません。
どこが間違っているのか、どなたか教えていただけないでしょうか。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int mday[12]={31,28,31,30,31,30,31,31,30,31,30,31};

int dayofweek(int year,int month,int day)
{
	if(month==1||month==2){
		year--;
		month+=12;
	}
	return ((year+year/4-year/100+year/400+(13*month+8)/5+day)%7);
}

int is_leap(int year)
{
	return(year%4==0 && year%100!=0 || year%400==0);
}

int monthdays(int year,int month)
{
	if(month==2)
		return (mday[month]+is_leap(year));
	return (mday[month]);
}

void make_calendar(int y,int m,char s[7][22])
{
	int i,k;
	int wd=dayofweek(y,m,1);
	int mdays=monthdays(y,m);
	char tmp[4];

	sprintf(s[0],"%10d / %02d      ",y,m);

	for(k=1;k<7;k++)
		s[k][0]='\0';
	
	k=1;
	sprintf(s[k],"%*s",3*wd,"");

	for(i=1;i<=mdays;i++){
		sprintf(tmp,"%3d",i);
		strcat(s[k],tmp);
		if(++wd%7==0)
			k++;
	}

	if(wd%7==0)
		k--;
	else{
		for(wd%=7;wd<7;wd++)
			strcat(s[k],"   ");
	}
	while(++k<7)
		sprintf(s[k],"%21s","");
}

void print(char sbuf[3][7][22],int n)
{
	int i,j;

	for(i=0;i<n;i++)
		printf("%s   ",sbuf[i][0]);
	putchar('\n');


	for(i=0;i<n;i++)
		printf(" 日 月 火 水 木 金 土   ");
	putchar('\n');
	

	for(i=0;i<n;i++)
		printf("----------------------  ");
	putchar('\n');


	for(i=1;i<7;i++){
		for(j=0;j<n;j++)
			printf("%s   ",sbuf[j][i]);
		putchar('\n');
	}
	putchar('\n');
}

void put_calendar(int y1,int m1,int y2,int m2)
{
	int y=y1;
	int m=m1;
	int n=0;
	char sbuf[3][7][22];

	while(y<=y2){
		if(y==y2&&m>m2) break;
		make_calendar(y,m,sbuf[n++]);
		if(n==3){
			print(sbuf,n);
			n=0;
		}
		m++;
		if(m==13&&y<y2){
			y++;
			m=1;
		}
	}
	if(n)
		print(sbuf,n);
}

int main()
{
	int y1,y2,m1,m2;
	printf("カレンダーを表\示します\n");
	printf("開始年月\n");
	printf("年:"); scanf("%d",&y1);
	printf("月:"); scanf("%d",&m1);
	printf("終了年月\n");
	printf("年:"); scanf("%d",&y2);
	printf("月:"); scanf("%d",&m2);

	putchar('\n');

	put_calendar(y1,m1,y2,m2);

	return 0;
}


box
記事: 2002
登録日時: 14年前

Re: カレンダーのプログラム

#2

投稿記事 by box » 10年前

試しに2015年の1月~12月のカレンダーを出力したところ、こんな風になりました。

コード:

      2015 / 01               2015 / 02               2015 / 03         
 日 月 火 水 木 金 土    日 月 火 水 木 金 土    日 月 火 水 木 金 土   
----------------------  ----------------------  ----------------------  
              1  2  3     1  2  3  4  5  6  7     1  2  3  4  5  6  7   
  4  5  6  7  8  9 10     8  9 10 11 12 13 14     8  9 10 11 12 13 14   
 11 12 13 14 15 16 17    15 16 17 18 19 20 21    15 16 17 18 19 20 21   
 18 19 20 21 22 23 24    22 23 24 25 26 27 28    22 23 24 25 26 27 28   
 25 26 27 28             29 30 31                29 30                  
                                                                        

      2015 / 04               2015 / 05               2015 / 06         
 日 月 火 水 木 金 土    日 月 火 水 木 金 土    日 月 火 水 木 金 土   
----------------------  ----------------------  ----------------------  
           1  2  3  4                    1  2        1  2  3  4  5  6   
  5  6  7  8  9 10 11     3  4  5  6  7  8  9     7  8  9 10 11 12 13   
 12 13 14 15 16 17 18    10 11 12 13 14 15 16    14 15 16 17 18 19 20   
 19 20 21 22 23 24 25    17 18 19 20 21 22 23    21 22 23 24 25 26 27   
 26 27 28 29 30 31       24 25 26 27 28 29 30    28 29 30 31            
                                                                        

      2015 / 07               2015 / 08               2015 / 09         
 日 月 火 水 木 金 土    日 月 火 水 木 金 土    日 月 火 水 木 金 土   
----------------------  ----------------------  ----------------------  
           1  2  3  4                       1           1  2  3  4  5   
  5  6  7  8  9 10 11     2  3  4  5  6  7  8     6  7  8  9 10 11 12   
 12 13 14 15 16 17 18     9 10 11 12 13 14 15    13 14 15 16 17 18 19   
 19 20 21 22 23 24 25    16 17 18 19 20 21 22    20 21 22 23 24 25 26   
 26 27 28 29 30 31       23 24 25 26 27 28 29    27 28 29 30 31         
                         30                                             

      2015 / 10               2015 / 11               2015 / 12         
 日 月 火 水 木 金 土    日 月 火 水 木 金 土    日 月 火 水 木 金 土   
----------------------  ----------------------  ----------------------  
              1  2  3     1  2  3  4  5  6  7                           
  4  5  6  7  8  9 10     8  9 10 11 12 13 14                           
 11 12 13 14 15 16 17    15 16 17 18 19 20 21                           
 18 19 20 21 22 23 24    22 23 24 25 26 27 28                           
 25 26 27 28 29 30       29 30 31                                       
                                                                        

月とその日数が合致していません。何となく1月分ずれているような気がします。
このあたりが、12月を表示しない原因になっていないでしょうか。
なお、私だったら、下記のとおり、毎月の日数を持たせる配列の先頭にわざと
ダミーのゼロを置いて、配列の要素番号と何月であるかが一致するようにします。
1個ずれているのは気持ちが悪いですから。

コード:

    int daytab[][MONTHS_PER_YEAR+1] = {                         /* 毎月の日数 */
        {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},    /* 平年 */
        {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},    /* 閏年 */
    };

最後に編集したユーザー box on 2015年3月21日(土) 00:05 [ 編集 1 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: カレンダーのプログラム

#3

投稿記事 by みけCAT » 10年前

5行目の

コード:

int mday[12]={31,28,31,30,31,30,31,31,30,31,30,31};

コード:

int mday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
としてみてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: カレンダーのプログラム

#4

投稿記事 by box » 10年前

期せずして同じような内容の回答が来ましたが、趣旨は要するにこういうことです。
1月だったら配列の[1]を、12月だったら配列の[12]を参照する方が
1月だったら配列の[0]を、12月だったら配列の[11]を参照するよりもわかりやすいはず。
なので、先頭にダミー(0でなくても何でもよい。参照しないので)を置いて、
わざと要素数13の配列を定義しているわけです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る