開始月と終了月を指定して、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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語 3 2022/11/09 13:27
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10個出力で改行したいのですが...
-
cshの文字列操作(0埋め)
-
scanfに文字が入力されたときに...
-
wsprintfの書式制御文字列につ...
-
すごろくに使用するサイコロ
-
ブラックジャック
-
1秒で動くインターバルタイマ
-
コマンドラインに出力した文字...
-
プログラムの作成
-
【C言語教えてください】sin波...
-
c言語でAからZまでを表示する...
-
小数点切捨て表示
-
プログラミング(じゃんけんゲ...
-
CTRL+Dでループを抜けるには
-
(C言語)西暦年月日を入力して...
-
ifなんですが
-
C言語です このプログラミング...
-
文字列のprint文
-
switch分のケースを範囲数?に...
-
線形探索法のプログラムについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
【C言語教えてください】sin波...
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
コマンドラインに出力した文字...
-
strcmp
-
4の倍数を論理演算で表す。。
-
C言語での、年複利の計算方法...
-
C言語 プログラミング
-
scanfに文字が入力されたときに...
-
hit&bolwのプログラミングがで...
-
%P と %X の違い
-
unsigned int型について
-
printf( " %2d", p * q );
-
cshの文字列操作(0埋め)
-
改行について 1行に何個かづ...
-
8人分のテストの点数を入力し、...
-
入力したお金の金額からお札の...
-
三角形の判別
-
テキストカーソル位置の取得
おすすめ情報