![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
開始月と終了月を指定して、3か月ごとにカレンダーを改行する
プログラムを作ってみました。
ところが、動作をさせてみたところ7月が配列tuki[12]において31日
と指定しているのにも関わらず25日分しか表示されません。
それと、たまに4月分が24日分しか表示されません。(試した限りでは、
4月を終了月に指定するとそうなりました。)
なにがおかしいためにこうなってしまうのでしょうか。
よろしくお願いいたします。
#include<stdio.h>
#include<string.h>
/*月の最初の日をメインプログラムに返す*/
int getyoubi(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);
}
/*カレンダーを3か月分表示させる*/
void print(char s[3][7][22],int n)
{
int i,j;
for(i=0;i<n;i++)
{
printf("%s ",s[i][0]);
}
printf("\n");
for(i=0;i<n;i++)
{
printf(" 日 月 火 水 木 金 土 ");
}
printf("\n");
for(i=0;i<n;i++)
{
printf("---------------------- ");
}
printf("\n");
for(i=1;i<7;i++)
{
for(j=0;j<n;j++)
{
printf("%s ",s[j][i]);
}
printf("\n");
}
printf("\n");
}
int main(void)
{
int nen1,tuki1,nen2,tuki2,tukiho,nenho,tukih,w,j;
char sbuf[3][7][22];
int tuki[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int k;
char tmp[4];
int count=0;
printf("カレンダーを表示します。\n");
printf("開始年月を入力せよ。\n");
printf("年:");
scanf("%d",&nen1);
printf("月:");
scanf("%d",&tuki1);
printf("終了年月を入力せよ。\n");
printf("年:");
scanf("%d",&nen2);
printf("月:");
scanf("%d",&tuki2);
/*最大3カ月分のカレンダーを格納する。*/
do{
w=getyoubi(nen1,tuki1,1);
sprintf(sbuf[count][0],"%10d / %02d ",nen1,tuki1);
for(k=1;k<7;k++)
{
sbuf[count][k][0]='\0';
}
sprintf(sbuf[count][1],"%*s",3*w,"");
k=1;
for(j=1;j<=tuki[tuki1-1];j++)
{
sprintf(tmp,"%3d",j);
strcat(sbuf[count][k],tmp);
if((j+w-1)%7==6)
{
k++;
}
}
do{
if((j+w-1)%7==6)
{
sprintf(sbuf[count][k],"%21s","");
}
else
{
do{
strcat(sbuf[count][k]," ");
j++;
}while((j+w-1)%7!=0);
}
k++;
}while(k!=7);
count++;
if(count==3)
{
print(sbuf,count);
count=0;
}
tuki1++;
if(tuki1==13)
{
tuki1=1;
nen1++;
}
}while(nen1<nen2 || nen1==nen2 && tuki1<=tuki2);
if(count)
{
print(sbuf,count);
}
return 0;
}
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
↓のプログラムは、参照URLから完動することを確認し、printf() を sprintf() に換え、3ヶ月分確保して処理しています。
おそらく、出力にバグがあるのではないでしょうか。/* Calender program by Mac OSX
* file name: rin.c
* compile: gcc rin.c
* execution: ./a.out
*/
#include <stdio.h>
#define LINE_NUM9
#define BUFF_SIZE24
#define LESS_0
#define MIDDLE1
#define GREATE2
#define input(comment, value) {printf(comment); scanf("%d", value);}
struct set1 {
char line[LINE_NUM][BUFF_SIZE];
} month[3];
void get_calen(int, int, int);
int main(void) {
int y, m,/* 年 月 */
i, j;
/* 年月を入力 */
input("year=", &y);
input("manth=", &m);
get_calen(MIDDLE, y, m);// 当月
m == 1 ? get_calen(LESS_, y - 1, 12) : get_calen(LESS_, y, m - 1);
m == 12 ? get_calen(GREATE, y + 1, 1) : get_calen(GREATE, y, m + 1);
printf("\n");
for (j = 0; j < 9; j++) {// 各行
for (i = 0; i < 3; i++)// 3ヶ月分を
printf("%-21s ", month[i].line[j]);// 左詰めで出力
printf("\n");
}
return 0;
}
void get_calen(int n, int y, int m) {
int d,/* 日 */
wd,/* 曜日 */
dm,/* 月の日数 */
i,/* 繰り返し用のカウンタ */
c;/* line[添字] */
char *j;
/* 表示年月 */
c = 0;
sprintf(month[n].line[c], "%4s[%d年 %d月]", " ", y, m);
/* y年m月が何日あるか */
switch(m) {
case 2:
if ( y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
dm = 29 ; /* 閏年 */
else
dm = 28 ;
break ;
case 4:
case 6:
case 9:
case 11:
dm = 30 ;
break ;
default:
dm = 31 ;
break ;
}
/* y年m月1日の曜日を求める */
if (m == 1 || m == 2) {
y-- ;
m += 12 ;
}
wd = (y + y/4 - y/100 + y/400 + (13*m+8)/5 +1) % 7 ;
/* 曜日欄 */
sprintf(month[n].line[++c], " 日 月 火 水 木 金 土");
sprintf(month[n].line[++c], " --------------------");
/* 空白の表示 */
j = month[n].line[++c];
for (i = 0; i < wd; i++)
j += sprintf(j, " %2s", " ");
/* 日付の表示 */
for (i = 1; i <= dm; i++) {
j += sprintf(j, " %2d", i);
wd ++ ;
if (wd % 7 == 0)
j = month[n].line[++c];
}
}
参考URL:http://www.asahi-net.or.jp/~qb3k-kwsk/rpg/progra …
No.2
- 回答日時:
追記:
7月の方は良く考えてないけど、手元の環境では治っちゃってる
#ログとらないもんだから無意識に直しちゃって、後でどう修正したのかわからなくなることがたまにあるorz
#月がずれてたのも同時に治っているなあ> 2010-01-01/2010-03-01
#まだ、3つ「まで」表示という部分には至ってない。頑張って直すべし。
#この公式って紀元前とかには通用しないのでは?西暦0年とか入力された時の扱いも含めて考える。
#2番目の日付に1番目の日付よりも前の日付を指定したらどうなるか試していない。
#ところで、2012年って4で割れて100で割れないけど…いいの?2月。
No.1
- 回答日時:
いくつか質問。
その1:
> }while((j+w-1)%7!=0);
は
> }while((j+w-1)%7!=6);
じゃないの?
その2:
tukiho,nenho,tukih
はこれから使うのかな?
その3(本題):
4月の処理をしているときに、
if((j+w-1)%7==6)
で分岐されるよね?一回目にはどっちを通るのかな?この時のjの値は何かな?
#「構造体」とか調べられるとコードが多少見やすくなる。
#あと、main関数にやることを殆どそのまま書こうとしていて少し長くなっている気がするので、うまい具合に関数を分割できたら見やすくなるんじゃないかな?
>その1:
自分でもよくわからないのですが、どうやら変数jは最終日の次の日になってるので、
6あまったら改行するのではなく0の時に改行をするようです。
実際に、それで私の環境ではうまく動作しました。
>その2:
tukiho,nenho,tukih
はこれから使うのかな?
いえ、前に修正した時の残り火です。すっかり忘れておりました。
混乱をさせてしまって申し訳ございません。
>4月の処理をしているときに、
if((j+w-1)%7==6)
で分岐されるよね?一回目にはどっちを通るのかな?この時のjの値は何かな?
申し訳ございません。おっしゃっている意味がよくわからないです。
回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
(C言語)めちゃくちゃな値にな...
-
テキストカーソル位置の取得
-
c言語でAからZまでを表示する...
-
scanfに文字が入力されたときに...
-
C言語で連立一次方程式
-
【C言語教えてください】sin波...
-
CTRL+Dでループを抜けるには
-
C言語について。 同じ年内で経...
-
C言語で以下の実行結果を教えて...
-
三平方の定理を求めるプログラム
-
10個出力で改行したいのですが...
-
wsprintfの書式制御文字列につ...
-
至急お願いします! ジャンケン...
-
C言語のC++で質問です。
-
カレンダーがうまく表示されない
-
C言語についてです学籍番号、名...
-
srand(time(NULL))の使い方
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
3つの整数を画面から入力して...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
テキストカーソル位置の取得
-
4の倍数を論理演算で表す。。
-
cshの文字列操作(0埋め)
-
【C言語教えてください】sin波...
-
10個出力で改行したいのですが...
-
wsprintfの書式制御文字列につ...
-
printfの出力内の文字をdefine...
-
error C2143: 構文エラー : ';'...
-
%P と %X の違い
-
C言語
-
strcmp
-
(C言語)めちゃくちゃな値にな...
-
コマンドラインに出力した文字...
-
スレッドとメッセージキューに...
-
printf( " %2d", p * q );
-
Visual Sutdio 2017 でのC言語...
-
3つの整数が等しいかどうか調...
おすすめ情報