No.17481![]() |
カレンダーの配列 投稿者---AAA(2004/10/24 13:45:30) |
||
カレンダーの表示の仕方で悩んでいます。 配列の表示の仕方がよく理解できていないのでそこを詳しく教えてください。月を3×4で表示がしたいです。途中まで作ってみましたが・・・ #include <stdio.h> void print_calendar( int num_days, int youbi ) { int i; int d; int x; for ( i = 0; i < ( youbi * 3 ); i++ ) { printf( " " ); } d = 1; x = youbi; do { printf( "%2d ", d ); d++; if ( x == 6 ) { printf( "\n" ); x = 0; } else { x++; } } while ( d <= num_days ); return; } int num_of_day( int y, int m) { int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if ( ( m == 2 ) && (((y % 400) == 0) || (((y % 100) != 0) && ((y % 4) == 0)))){ return 29; } else { return num_days[m-1]; } } int zeller( int y, int m, int d ) { if ( ( m == 1 ) || ( m == 2 ) ) { y = y - 1; m = m + 12; } return (y + (y/4) - (y/100) + (y/400) + ((13 * m + 8 ) / 5)+ d) % 7; } int first_day( int y, int m ) { return zeller( y, m, 1 ); } main() { int t,r,e; int calendar[12][7][6];//12は月、7は1週間、6は最大の週// int y; int m; printf( "カレンダーを表示する年を入力してください " ); scanf( "%d", &y ); for(t=0;t<12;t++){ for(e=0;e<6;e++){ for(r=0;r<7;r++){ calendar[t][r][e]; } } } printf("%35d年\n\n", y); for(m=1;m<=12; m += 3){ printf("%10d月%21d月%21d月\n""日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n",m,m+1,m+2); print_calendar( num_of_day(y, m), first_day(y, m) ); printf("\n\n"); } return 0; } |
No.17482![]() |
Re:カレンダーの配列 投稿者---かずま(2004/10/24 17:00:29) |
||
> カレンダーの表示の仕方で悩んでいます。 それ以前に、プログラムの投稿の仕方で悩んでください。 【掲示板ご利用上の注意】を読めば悩むことはないはずですが。 > 配列の表示の仕方がよく理解できていないのでそこを詳しく教えてください。 > 月を3×4で表示がしたいです。途中まで作ってみましたが・・・ この掲示板の過去ログ No.505 でも見て研究してください。 |
No.17483![]() |
Re:カレンダーの配列 投稿者---AAA(2004/10/24 17:37:12) |
||
すみませんでした。読んでいませんでした。 505を見させていただきましたが どうも配列の出力が理解できないです。 例えばこのプログラムだとどのようになるのでしょうか? #include <stdio.h> void print_calendar( int num_days, int youbi ) { int i; int d; int x; for ( i = 0; i < ( youbi * 3 ); i++ ) { printf( " " ); } d = 1; x = youbi; do { printf( "%2d ", d ); d++; if ( x == 6 ) { printf( "\n" ); x = 0; } else { x++; } } while ( d <= num_days ); return; } int num_of_day( int y, int m) { int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if ( ( m == 2 ) && (((y % 400) == 0) || (((y % 100) != 0) && ((y % 4) == 0)))){ return 29; } else { return num_days[m-1]; } } int zeller( int y, int m, int d ) { if ( ( m == 1 ) || ( m == 2 ) ) { y = y - 1; m = m + 12; } return (y + (y/4) - (y/100) + (y/400) + ((13 * m + 8 ) / 5)+ d) % 7; } int first_day( int y, int m ) { return zeller( y, m, 1 ); } main() { int t,r,e,w; int calendar[12][7][6];//12は月、7は1週間、6は最大の週// int y; int m; printf( "カレンダーを表示する年を入力してください. " ); scanf( "%d", &y ); for(t=0;t<12; t++){ for(e=0;e<6;e++){ for(r=0;r<7;r++){ calendar[t][r][e]; } } } printf("%35d年\n\n", y); for(m=1;m<=12; m += 3){ printf("%10d月%21d月%21d月\n""日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n",m,m+1,m+2); for (e = 0; e < 6; e++) for (w = -1; w < 2; w++) { for (r = 0; r < 7; r++) printf(calendar[m+w][r][e] ? "%3d" : " ", calendar[m+w][r][e]); printf(w==1 ? "\n" : " "); } print_calendar( num_of_day(y, m), first_day(y, m) ); printf("\n\n"); } return 0; } |
No.17485![]() |
Re:カレンダーの配列 投稿者---AAA(2004/10/24 18:08:46) |
||
間違えてました。こちらを変化させてほしいです。 カレンダー表示なのでやはり配列の表示がよくわからないです。 #include <stdio.h> void print_calendar( int num_days, int youbi ) { int i; int d; int x; for ( i = 0; i < ( youbi * 3 ); i++ ) { printf( " " ); } d = 1; x = youbi; do { printf( "%2d ", d ); d++; if ( x == 6 ) { printf( "\n" ); x = 0; } else { x++; } } while ( d <= num_days ); return; } int num_of_day( int y, int m) { int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if ( ( m == 2 ) && (((y % 400) == 0) || (((y % 100) != 0) && ((y % 4) == 0)))){ return 29; } else { return num_days[m-1]; } } int zeller( int y, int m, int d ) { if ( ( m == 1 ) || ( m == 2 ) ) { y = y - 1; m = m + 12; } return (y + (y/4) - (y/100) + (y/400) + ((13 * m + 8 ) / 5)+ d) % 7; } int first_day( int y, int m ) { return zeller( y, m, 1 ); } main() { int t,r,e,w; int calendar[12][7][6];//12は月、7は1週間、6は最大の週// int y; int m; printf( "カレンダーを表示する年を入力してください. " ); scanf( "%d", &y ); for(t=0;t<12; t++){ for(e=0;e<6;e++){ for(r=0;r<7;r++){ calendar[t][r][e]; } } } printf("%35d年\n\n", y); for(m=1;m<=12; m += 3){ printf("%10d月%21d月%21d月\n""日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土\n",m,m+1,m+2); print_calendar( num_of_day(y, m), first_day(y, m) ); printf("\n\n"); } return 0; } |
No.17486![]() |
Re:カレンダーの配列 投稿者---かずま(2004/10/24 19:09:28) |
||
> カレンダー表示なのでやはり配列の表示がよくわからないです。 配列の内容を表示するには、まず、配列 calendar[12][6][7] にカレンダーの データを作らないといけません。質問のプログラムではそれを作っていません。 次に表示ですが、作った配列を print_calendar に渡さないと表示できません。 3か月まとめて表示するのですから、3か月の先頭のアドレスを渡してやります。 #include <stdio.h> void print_calendar(int calendar[][6][7]) { int e, t, r; for (e = 0; e < 6; e++) { for (t = 0; t < 3; t++) { for (r = 0; r < 7; r++) if (calendar[t][e][r]) printf("%2d ", calendar[t][e][r]); else printf(" "); printf(" "); } printf("\n"); } printf("\n"); } int num_of_day(int y, int m) { int num_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (m == 2 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) return 29; return num_days[m - 1]; } int zeller(int y, int m, int d) { if (m <= 2) { y--; m += 12; } return (y + y/4 - y/100 + y/400 + (13*m + 8)/5 + d) % 7; } int first_day(int y, int m) { return zeller(y, m, 1); } int main(void) { int calendar[12][6][7] = { 0 }; //12は月、6は最大の週、7は 1週間 int y, m, d, e, num_days, youbi; printf("カレンダーを表示する年を入力してください. "); scanf("%d", &y); for (m = 1; m <= 12; m++) { num_days = num_of_day(y, m); youbi = first_day(y, m); e = 0; for (d = 1; d <= num_days; d++) { calendar[m-1][e][youbi] = d; if (++youbi == 7) { youbi = 0; e++; } } } printf("%35d年\n\n", y); for (m = 1; m <= 12; m += 3) { printf("%10d月%21d月%21d月\n" "日 月 火 水 木 金 土 " "日 月 火 水 木 金 土 " "日 月 火 水 木 金 土\n", m, m + 1, m + 2); print_calendar(&calendar[m-1]); } return 0; } |
No.17487![]() |
Re:カレンダーの配列 投稿者---AAA(2004/10/24 19:34:22) |
||
丁寧な解説ありがとうございます。 確認なんですが for (e = 0; e < 6; e++) { for (t = 0; t < 3; t++) { for (r = 0; r < 7; r++) if (calendar[t][e][r]) printf("%2d ", calendar[t][e][r]); else printf(" "); printf(" "); } printf("\n"); } このプログラムは表示する時に3ヶ月ごとにするためtがt = 0; t < 3; t++になるんですよね? for (m = 1; m <= 12; m++) { num_days = num_of_day(y, m); youbi = first_day(y, m); e = 0; for (d = 1; d <= num_days; d++) { calendar[m-1][e][youbi] = d; if (++youbi == 7) { youbi = 0; e++; } } } あとこのプログラムはdが1からその月の最後まで表示するプログラムで youbiが7になったらyoubiを0にしてeを1繰上げるプログラムですよね? それと3次元関数のところでなぜm-1になるのかがわからないのですが・・・どういうことでしょう? |
No.17574![]() |
Re:カレンダーの配列 投稿者---かずま(2004/10/27 22:45:14) |
||
> このプログラムは表示する時に3ヶ月ごとにするためtがt = 0; t < 3; t++になるんですよね? そうです。 > あとこのプログラムはdが1からその月の最後まで表示するプログラムで いいえ、表示はしません。配列 calendar に値を設定しているだけです。 > youbiが7になったらyoubiを0にしてeを1繰上げるプログラムですよね? そうです。 > それと3次元関数のところでなぜm-1になるのかがわからないのですが・・・ > どういうことでしょう? 3次元関数ではなく、3次元配列ですね。m は、月ですから、1〜12 です。 1月のデータは calendar[0] に、12月のデータは calendar[11] に入ります。 |
No.17701![]() |
Re:カレンダーの配列 投稿者---AAA(2004/11/01 22:16:25) |
||
ありがとうございました。 今回はカレンダー&スケジュールにしようと思ってます。 一ヶ月の予定を入れてそれを出力するプログラムを。 例えば1日に飲み会、5日に会議とかを。 それと毎週確実な行事は曜日指定で出力したいのですが、 その方法が思いつきません。 やり方は上のプログラムを変化して2次元配列で 数字と文字を交互に出力したいのですが・・・ アドバイスをお願いします。 |
No.17708![]() |
Re:カレンダーの配列 投稿者---AAA(2004/11/02 02:21:25) |
||
このプログラムを変化させようと思います。 日付の間にスペースはできたのですが行事をいれる事が全然思いつきません。アドバイスお願いします。 #include <stdio.h> void print(int ca[12][24][7]) { int a,b,c; for(a=0;a<24;a++){ for(b=0;b<1;b++){ for(c=0;c<7;c++){ if(ca[b][a][c]){ printf("%9d ", ca[b][a][c]); //配列に関係するときその数字を入力 } else{ printf(" "); //それ以外の時はスペース } } printf(" "); } printf("\n"); } printf("\n"); } int number(int y,int m){ int days[]={31,28,31,30,31,30,31,31,30,31,30,31}; if(m==2 && y%4==0 && (y%100 != 0 || y%400==0)){ //うるう年の計算 return 29; } else{ return days[m-1]; //うるう年以外の2月の表示28 } } int nissu(int y,int m,int d){ if(m<=2){ y--; m +=12; } return (y+y/4-y/100+y/400+(13*m+8)/5+d)%7; } int first(int y,int m){ return nissu(y,m,1); } int main(void) { int ca[12][24][7]={0}; int y,m,d,e,days,youbi; printf("カレンダーを表示する年を入力 : "); scanf("%d",&y); printf("カレンダーを表示する月を入力 : "); scanf("%d",&m); days=number(y,m); youbi = first(y,m); e=0; //最初の数値を0とし、日数は1からその月の最大 for(d=1;d<=days;d++){ //までいき、それを配列と連結させて、youbiが7に ca[m-1][e][youbi] = d; //なったらyoubiを0に戻し、eを追加する if(++youbi == 7){ youbi =0; e +=4; } } printf("%30d月\n"" 日 月 火 水 木 金 土\n",m); print(&ca[m-1]); return 0; } |
No.17742![]() |
Re:カレンダーの配列 投稿者---かずま(2004/11/03 16:57:19) |
||
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define SCHEDULE_FILE "schedule.txt" int cal[6][7]; char *msg[12][31+1]; char *w_msg[7]; int dayofweek(int y, int m, int d) { static int t[] = { 0, 3, 2, 5, 7, 3, 5, 1, 4, 6, 2, 4 }; y -= m < 3; return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; } int days(int y, int m) { static int t[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; return t[m-1] + (m==2 && y/4==0 && (y/100!=0 || y/400==0)); } void read_schedule(int year) { char buf[256], dow[256], c, *p; int y = year, m, d, n; FILE *fp = fopen(SCHEDULE_FILE, "r"); if (fp == NULL) return; while (fgets(buf, sizeof buf, fp)) { if (p = strchr(buf, '\n')) *p = '\0'; if (sscanf(buf, "%d %c", &m, &c) == 1) y = m; else if (sscanf(buf, "%d%*c%d %n%c", &m, &d, &n, &c) == 3) { if (y == year && m>=1 && m<=12 && d>=1 && d<=31) msg[m-1][d] = strdup(buf + n); } else if (sscanf(buf, "%s %n%c", dow, &n, &c) == 2) { static char w[] = "日月火水木金土"; dow[2] = '\0'; p = strstr(w, dow); if (p) w_msg[(p - w)/2] = strdup(buf + n); } } fclose(fp); } void print(int y, int m) { int row, w, d; char *s; printf("%35d 年 %2d 月\n\n 日 月 火 水" " 木 金 土\n\n", y, m); for (row = 0; row < 6; row++) { for (w = 0; w < 7; w++) { d = cal[row][w]; printf(d ? "%3d " : " ", d); } putchar('\n'); for (w = 0; w < 7; w++) { d = cal[row][w]; s = msg[m-1][d] ? msg[m-1][d] : d && w_msg[w] ? w_msg[w] : ""; printf(" %-10.10s", s); } puts("\n"); } } int main(int argc, char *argv[]) { time_t t = time(0); struct tm *p = localtime(&t); int y = p->tm_year + 1900; int m = p->tm_mon + 1; int d, w, n, row = 0; if (argc == 3) y = atoi(argv[1]), m = atoi(argv[2]); else if (argc == 2) m = atoi(argv[1]); read_schedule(y); if (m < 1 || m > 12) return 1; w = dayofweek(y, m, 1); n = days(y, m); for (d = 1; d <= n; d++) { cal[row][w] = d; if (++w == 7) w = 0, row++; } print(y, m); return 0; } ---- SCHEDULE_FILE ---- 2003 11/3 文化の日 2004 10/11 体育の日 11/3 文化の日 11/23 勤労感謝の日 水 定例会議 文字列が全角5文字を超える場合どうするかは自分で考えてください。 |