忙しい現代人の腰&肩のお悩み対策!

西暦年月日を入力して、その日の曜日を表示させるプログラムを作りたいのですが、とりあえず、やってみましたが…

int main(void)
{

int i,y,m,d,dy,dw;

int D[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

printf("Year?");

scanf("%d",&y);

printf("Month?");

scanf("%d",&m);

printf("Day?");

scanf("%d",&d);

for(i=0;i<=m-1;i++){
dy = d + D[i] ;
}

if(m>=3){
if(y % 4 == 0){
if(y % 400 == 0){
dy = dy + 1 ;
}
else if(y % 100 ==0){
dy = dy ;
}
else{
dy = dy + 1 ;
}
}

else if(y % 4 == 1 || y % 4 == 2 || y % 4 == 3 ){
dy = dy ;
}
}
dw = (dy -1 + ( y + ( y - 1 )/4 - ( y - 1 )/100 + ( y - 1 )/400))%7 ;

if (dw == 0) printf("Sunday\n");
else if (dw == 1) printf("Monday\n");
else if (dw == 2) printf("Tuesday\n");
else if (dw == 3) printf("Wednesday\n");
else if (dw == 4) printf("Thursday\n");
else if (dw == 5) printf("Friday\n");
else if (dw == 6) printf("Saturday\n");

return 0 ;

}
このプログラムを各年の1月1日~2月28日で試してみると、うまくいくのですが、3月1日に入るとなぜかうまく働いてくれません。(ちなみに2005年の11月では偶然うまくいっています。)その理由が分からないのでどなたか教えてください。ちなみに、この一連のプログラムを行うにはもっと簡単に行える関数というかコマンド?みたいなものがあるようですが、基本的に各年の1月1日を、
(y+(y-1)/4-(y-1)/100+(y-1)/400)%7で(0:Sunday~)、同年の○月○日は1月1日から△日経過しているという考え方で、曜日を割り出すプログラムにしなければならないといけないので、注文が多いですがよろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (8件)

プログラムのおかしいところについては#1の回答のとおりです。


したがって、
>int D[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
これを
>int D[]={0,31,59,90,120,151,181,212,243,273,304,335};
>//各月の前月までの年初からの日数
として、
>for(i=0;i<=m-1;i++){
> dy = d + D[i] ;
>}

>dy = d[m-1] + d;
とするという解法もあります。あらかじめ足しておいてはいけないということはないでしょう。

ただ、標準関数に日付の関数はあります。
もちろん制限はあって、time_tのサイズが32bit(=signed long int)の場合、1901年12月14日05:45:52~2038年1月19日12:14:07の間だけが正常に動作するようになっていますし、上記のアルゴリズムとは違って1970年1月1日00:00:00を基準とした秒数をもとにして計算しているため、今回は利用できませんね。

ところで、
> ちなみに2005年の11月では偶然うまくいっています。
の理由について回答が出ていませんが、それは、2005年1月と2005年10月がたまたま同じ曜日で始まっていてかつ、1月と10月が同じ日数(31日)だからです。
    • good
    • 0
この回答へのお礼

2005年11月で偶然うまくいっている理由についてもコメントしていだたきありがとうございます。

お礼日時:2005/11/29 23:09

蛇足ながら、1582年を境にグレゴリオ暦とユリウス暦が使い分けられています。

そのパッチを加えました。
#include <stdio.h>
#include <stdlib.h>

int
getint(void)
{
char buf[BUFSIZ];
fgets(buf, BUFSIZ, stdin);
return (atoi(buf));
}

int
main(void)
{
int i, y, m, d, dy, dw;
int D[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char *Week[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday" };
printf("Year?");
y = getint();
printf("Month?");
m = getint();
printf("Day?");
d = getint();

for (i = 0; i <= m - 1; i++) {
d += D[i];
}
dy = d;
if (m >= 3) {
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)) dy++;
}
dy += y * 365 + y / 4 - y / 100 + y / 400;
/* printf("dy = %d\n", dy); */
if (dy >= 578101) { /* 1582年10月15日以降はグレゴリオ暦 */
dw = (dy + 6) % 7;
}
else if (dy <= 578090) { /* 1582年10月4日以前はユリウス暦 */
dy = d;
if (m >= 3) {
if (y % 4 == 0) dy++;
}
dy += y * 365 + y / 4;
dw = (dy + 4) % 7;
}
else {
printf("その日は存在しません。\n");
return(0);
}
printf("%s\n", Week[dw]);
return 0;
}
    • good
    • 0
この回答へのお礼

暦が1582年を境に違うなんて初めて知りました。親切にありがとうございます!

お礼日時:2005/11/29 23:12

がると申します。


んっと。曜日の算出にはいくつか種類がありますが、有名なツェラーの公式をお勧めします。
どうでしょうか?

参考URL:http://www004.upp.so-net.ne.jp/s_honma/doweek.ht …
    • good
    • 0

>この一連のプログラムを行うにはもっと簡単に行える関数というかコマンド?みたいなものがあるようですが


蛇足ですが…
#include <stdio.h>
#include <time.h>

int
getint(void)
{
char buf[BUFSIZ];
fgets(buf, BUFSIZ, stdin);
return (atoi(buf));
}

int
main(void)
{
struct tm day;
time_t time;

char *Week[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday" };
printf("Year?");
day.tm_year = getint() - 1900;
printf("Month?");
day.tm_mon = getint() - 1;
printf("Day?");
day.tm_mday = getint();
day.tm_hour = day.tm_min = day.tm_sec = 0;
time = mktime(&day);
localtime_r(&time, &day);

printf("%s\n", Week[day.tm_wday]);
return 0;
}
    • good
    • 0

#include <stdio.h>



int
getint(void)
{
char buf[BUFSIZ];
fgets(buf, BUFSIZ, stdin);
return (atoi(buf));
}

int
main(void)
{
int i, y, m, dy, dw;
int D[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char *Week[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday" };
printf("Year?");
y = getint();
printf("Month?");
m = getint();
printf("Day?");
dy = getint();

for (i = 0; i <= m - 1; i++) {
dy += D[i];
}
if (m >= 3) {
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)) dy++;
}
dw = (dy - 1 + (y + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400)) % 7;

printf("%s\n", Week[dw]);
return 0;
}
    • good
    • 0

#3です。

書き間違えてました。
>int D[]={0,31,59,90,120,151,181,212,243,273,304,335};
最後の335は334の間違い。
    • good
    • 0

//何かの参考に


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

int isLeapYear(unsigned y){
return ((0 == y % 400)||((0 == y % 4)&&(0 != y % 100)));
}

unsigned leapDays(unsigned y){
/* 基準日から指定年までの閏日の日数 */
return (y/4 - y/100 + y/400);
}

unsigned daysFromYearTop(unsigned y, unsigned m, unsigned d){
/* 指定日の年頭からの日数 */
static unsigned daysOfMonth[]={
NULL, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
return (daysOfMonth[m]+((m>2 && isLeapYear(y))? 1:0) + d);
}

unsigned long days(unsigned y, unsigned m, unsigned d){
/* 基準日から指定日までの通算日数 */
unsigned lastYear=y-1;

return(leapDays(lastYear) + lastYear*365 + daysFromYearTop(y, m, d));
}
#define JAPANESE 0
#define ENGLISH 1
#define ENGSHORT 2
const char *week_day(unsigned long days,int country){
/* 基準日からの通算日を指定した時の曜日を文字列で返す */
static const char *weekDays[][7]={
{"日", "月", "火", "水", "木", "金", "土"},
{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
{"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}
};
return(weekDays[country][days % 7]);
}

int main(void){
unsigned y, m, d;

printf("Year?");
scanf("%u",&y);
printf("Month?");
scanf("%u",&m);
printf("Day?");
scanf("%u",&d);

printf("%s\n",week_day(days(y,m,d), ENGLISH));//通算日の曜日

return(EXIT_SUCCESS);
}
    • good
    • 0

>for(i=0;i<=m-1;i++){


>dy = d + D[i] ;
>}
これでは前月のみの日付が加算されるだけです。
だから2月までならうまくいくわけです。

簡単に修正するならこんな感じでしょうか。
dy = d;
for (i = 0; i < = m - 1; i++)
{
dy += D[i] ;
}

Cの標準関数で日付関数はなかったと思います。
日付計算はよく使われるので探せばライブラリがありそうですが。
参考URLに日付関数のサンプルがありましたので参考にしてみてはいかがでしょう。

参考URL:http://hp.vector.co.jp/authors/VA016117/date.html
    • good
    • 0
この回答へのお礼

ありがとうございました。無事解決しました。感謝しいたします!

お礼日時:2005/11/29 23:06

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qカレンダープログラム、曜日の出力について。

西暦、月、日(1900年1月1日以降対象)を入力して、曜日を求めるプログラムを考えています。
過去の質問なども参考にしたんですが、プログラムがうまく動かず困っています。
プログラム中コメントの日数を変える辺りに不備があるかと思い色々試しましたが、曜日がずれてしまいますし開始1900年1月1日も月曜なのに水曜と出力されます。
forやifの条件の記述がおかしいのでしょうか?
なにか根本的な所が欠如しているのでしょうか、回答をよろしくお願いします。
始めのgetsの所はあえてです。
#include<stdio.h>
#include<stdlib.h>

int main(void)

{
char ss[9],cop1[5],cop2[3],cop3[3];

int year,manth,day,aa,cc,i,f;

gets(ss);

ss[8] = 0;
cop1[4] = 0;
cop2[2] = 0;
cop3[2] = 0;

for(i = 0;i <= 3;i++){
cop1[i] = ss[i];
}
for(i = 0;i <= 1;i++){
cop2[i] = ss[i+4];
}
for(i = 0;i <= 1;i++){
cop3[i] = ss[i+6];
}
year = atoi(cop1);
manth = atoi(cop2);
day = atoi(cop3);

printf("%d年%d月%d日",year,manth,day);

for(f = 1900; f <= year; f++){  //閏年か平年で日数を変える
if((year%4) == 0 && year != 1900){
aa += 366;
}
else{
aa += 365;
}
}
if((year%4) == 0 && manth >= 3 ){//閏年かつ3月以降日数+1
aa += 1;
}

switch(manth){
case 1:
cc = (aa + day)%7;
break;
case 2:
cc = (aa + 31 +day)%7;
break;
case 3:
cc = (aa + 59 +day)%7;
break;
case 4:
cc = (aa + 90 +day)%7;
break;
case 5:
cc = (aa + 120 +day)%7;
break;
case 6:
cc = (aa + 151 +day)%7;
break;
case 7:
cc = (aa + 181 +day)%7;
break;
case 8:
cc = (aa + 212 +day)%7;
break;
case 9:
cc = (aa + 243 +day)%7;
break;
case 10:
cc = (aa + 273 +day)%7;
break;
case 11:
cc = (aa + 304 +day)%7;
break;
case 12:
cc = (aa + 334 +day)%7;
break;
}
switch(cc){
case 1:
printf(" (月)");
break;
case 2:
printf(" (火)");
break;
case 3:
printf(" (水)");
break;
case 4:
printf(" (木)");
break;
case 5:
printf(" (金)");
break;
case 6:
printf(" (土)");
break;
case 0:
printf(" (日)");
break;
}

return 0;

}

西暦、月、日(1900年1月1日以降対象)を入力して、曜日を求めるプログラムを考えています。
過去の質問なども参考にしたんですが、プログラムがうまく動かず困っています。
プログラム中コメントの日数を変える辺りに不備があるかと思い色々試しましたが、曜日がずれてしまいますし開始1900年1月1日も月曜なのに水曜と出力されます。
forやifの条件の記述がおかしいのでしょうか?
なにか根本的な所が欠如しているのでしょうか、回答をよろしくお願いします。
始めのgetsの所はあえてです。
#include<stdio...続きを読む

Aベストアンサー

★追記。
・質問者さんのソースを元に書き直してみました。
 参考にして下さい。

#include <stdio.h>

// break 付きのキーワード
#define CASE  break;case
#define DEFAULT  break;default

// 西暦から閏年の判定
int FuncIsLeapYear( int year )
{
 if ( !(year % 3200) ) return 0;  // 平年(3200で割れる年)
 if ( !(year % 400) ) return 1;  // 閏年(400で割れる年)
 if ( !(year % 100) ) return 0;  // 平年(100で割れる年)
 if ( !(year % 4) ) return 1;  // 閏年(4で割れる年)
 return 0;       // 平年(それ以外の年)
}

// メイン関数
int main( void )
{
 static const char *table[] = { "日", "月", "火", "水", "木", "金", "土" };
 // 宣言
 int year = 0;
 int month = 0;
 int day = 0;
 int week = 0;
 // カウンタ
 int days;
 int i;
 
 // 年月日の入力
 scanf( "%04d/%02d/%02d", &year, &month, &day );
 // 1900年以降の日数を数える
 for ( days = 0, i = 1900 ; i < year ; i++ ){
  days += (FuncIsLeapYear(i) ? 366 : 365);
 }
 // 1月1日から日数を加える
 switch ( month ){
  CASE 1: days += 0;
  CASE 2: days += 31;
  CASE 3: days += 31 + 28;
  CASE 4: days += 31 + 28 + 31;
  CASE 5: days += 31 + 28 + 31 + 30;
  CASE 6: days += 31 + 28 + 31 + 30 + 31;
  CASE 7: days += 31 + 28 + 31 + 30 + 31 + 30;
  CASE 8: days += 31 + 28 + 31 + 30 + 31 + 30 + 31;
  CASE 9: days += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
  CASE 10: days += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
  CASE 11: days += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
  CASE 12: days += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
 }
 // 3月以降で閏年なら+1日
 if ( (month >= 3) && FuncIsLeapYear(year) ){
  days++;
 }
 // 入力した日付を加える
 days += day;
 // 曜日の計算
 week = (days % 7);
 // 表示
 printf( "year = %d\n", year );
 printf( "month = %d\n", month );
 printf( "day = %d\n", day );
 printf( "week = %s\n", table[week] );
 return 0;
}
以上。

★追記。
・質問者さんのソースを元に書き直してみました。
 参考にして下さい。

#include <stdio.h>

// break 付きのキーワード
#define CASE  break;case
#define DEFAULT  break;default

// 西暦から閏年の判定
int FuncIsLeapYear( int year )
{
 if ( !(year % 3200) ) return 0;  // 平年(3200で割れる年)
 if ( !(year % 400) ) return 1;  // 閏年(400で割れる年)
 if ( !(year % 100) ) return 0;  // 平年(100で割れる年)
 if ( !(year % 4) ) return 1;  // ...続きを読む

Q曜日を求めるプログラムはどうやるの?

ただいま、C言語に苦戦中です。教えてください
2001年の月日の入力データから、曜日を求めるプログラム。
(実行結果例)
月を入力してください: 9↓
日を入力して下さい : 15↓

9月15日は土曜日です。

Aベストアンサー

またまたarthurです。

1月~12月までの各月の日数を12コの配列に入れ、
1月から入力してもらった月の1つ前の月までの日数を合計します。
例)9月と入力された場合
1月の日数(31日)+2月の日数(28日)+・・・+8月の日数(31日)
さらに入力された日にち分を加算します。
例)15日と入力された場合
1月~8月の合計日数+15日
その合計の値をさらに7(1週間=7日)で割ります。
7で割った余りの数字によって曜日を割り当てます。
1月1日(月)が最初なので、余りが1の時月曜日とすると、余りが2の時は・・・

と、まぁ、ヒントはここまでです^^;
後は自分の力でがんばってください。

QカレンダーのC言語プログラムを教えてください!

西暦年と月を入力すると、その年月のカレンダーが出てくる万年カレンダーのC言語プログラムを教えてください!

その出力結果が
2***年 *月
月 火 水 木 金 土 日 月 火 水 木 金 土 日
1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 16 17 18 19 20 21 22 23 24 25 26 27 28
29 30 31

というように二週間ごとに表示するもので、
うるう年の判別ができるものになるようにしたいのですが。
年=n月=g
で入力するものを作りたいんです。
よろしくお願いします!!!(>_<)

Aベストアンサー

なんとなく作りました。
入力に関してはそちらで考えてください

#include<stdio.h>

int dayofw(int ,int ,int );

void main()
{
int y, m, dw, i, cnt, j;
char week[7][2]={"日", "月", "火", "水", "木", "金", "土"};
int mday[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

printf("年=");//入力
scanf("%d", &y);

printf("月=");
scanf("%d", &m);

if((y%4)==0 && (y%100) != 0 || (y%400) == 0){
mday[1] = 29;
}else{
mday[1] = 28;
}

dw=dayofw(y, m, 1);
cnt=dw;

printf("%d年%d月\n ", y, m);
for(j=0; j<2; j++){
for(i=0; i<7; i++){
printf(" %s ", week[i]);
}
}
printf("\n");

for(i=0; i<dw; i++){
printf(" ");
}
for(i=1; i<=mday[m-1]; i++){
printf(" %3d ", i);
cnt++;
if(cnt==14){
printf("\n");
cnt=0;
}
}
printf("\n");
}

int dayofw(int y, int m, int d)
{
int y1, yobi;

y1=(y+(y/4)-(y/100)+(y/400)+(2.6*m+1.6)+d);
yobi=y1%7;

return(yobi);
}

なんとなく作りました。
入力に関してはそちらで考えてください

#include<stdio.h>

int dayofw(int ,int ,int );

void main()
{
int y, m, dw, i, cnt, j;
char week[7][2]={"日", "月", "火", "水", "木", "金", "土"};
int mday[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

printf("年=");//入力
scanf("%d", &y);

printf("月=");
scanf("%d", &m);

if((y%4)==0 && (y%100) != 0 || (y%400) == 0){
mday[1] = 29;
}else{
mday[1] = 28;
}

dw=dayofw(y, m, 1);
cnt...続きを読む

QC言語でのカレンダー作成

今、C言語でカレンダーを表示させるプログラムを作成しています

西暦と月を入力すると、その年、その月の1ヶ月分のカレンダーが表示されるプログラムを作りました

そこで、次は入力した月から3ヶ月分のカレンダーを表示させるプログラムを作成したいのですが、どなたか教えてくださいませんか?

配列を使う方法や文字列など色々な方法があると伺って、どの方法が作りやすいのかわからないんです・・・

borland c を使用しています

Aベストアンサー

こんにちは。

前提として、作成するプログラムがコンソールアプリで、コンソール画面
にカレンダーを表示する場合ですが。。。
※以下は、あくまで一例です。

■縦方向に並べて表示する場合
※こちらは、#1さんの言われるように、単純に作成済みの1ヶ月カレンダー
 表示プログラムを、3回呼ぶだけで良いと思います。

1)既に作成済みのカレンダー表示を行うプログラムを関数化します。
  例)
  void DispMonth( int nYear, int nMonth );
   int nYear  : カレンダーの年
   int nMonth : カレンダーの月

2)入力された[年]、[月]を基準にして、forループなどで、[月]及び[年]を
  変えながら、1)の関数を呼出す。

 入力された[月]を中央にして、前後3ヶ月分のカレンダーを表示する場合、
 ================================================
 int nYear, nMonth;
 int m, nYY, nMM;
 nYear = 2010;  /* ←入力[年]とします */
 nMonth = 11;   /* ←入力[月]とします */
 /* 月単位のループ処理 */
 for ( m=nMonth-1; m<=nMonth+1; ++m ) {
   nYY = nYear;
   nMM = m;
   if ( nMM < 1 ) {
     nMM += 12;
     nYY--;
   }
   else if ( nMM > 12 ) {
     nMM -= 12;
     nYY++;
   }
   DispMonth( nYY, nMM );
   /* 必要であれば、ここで空白行などを出力し間隔を調整する */
 }
 ================================================
 のような処理になると思います。

■横方向に並べて表示する場合
※こちらの場合は、少し工夫が必要になります。

1)まず、作成済みのカレンダー表示を行うプログラムを組み直して、週単位
  (第1週~第6週)で表示を行う関数にします。
  例)
  void DispWeek( int nYear, int nMonth, int nWeek );
   int nYear  : カレンダーの年
   int nMonth : カレンダーの月
   int nWeek : 週単位のインデックス(1~6)
 ※出力の際、行末には改行を付加しないようにしておきます。
 ※週インデックスが、その月の週の数を越えた場合は、空白(スペース等)
  を出力するようにしておきます。

2)入力された[年]、[月]を基準にして、forループなどで、[月]、[年]、及び、
  [週のインデックス]を変えながら、1)の関数を呼出す。

 入力された[月]を中央にして、前後3ヶ月分のカレンダーを表示する場合、
 ================================================
 int nYear, nMonth;
 int m, nYY, nMM, nWeek;
 nYear = 2010;  /* ←入力[年]とします */
 nMonth = 11;   /* ←入力[月]とします */
 /* 必要であれば、ここで年、月、及び、曜日名などの表示を行う */
 ~~~
 /* 週単位のループ処理 */
 for ( nWeek=1; nWeek<=6; ++nWeek ) {
   /* 月単位のループ処理 */
   for ( m=nMonth-1; m<=nMonth+1; ++m ) {
     nYY = nYear;
     nMM = m;
     if ( nMM < 1 ) {
       nMM += 12;
       nYY--;
     }
     else if ( nMM > 12 ) {
       nMM -= 12;
       nYY++;
     }
     DispWeek( nYY, nMM, nWeek );
     /* 必要であれば、ここでスペースなどを出力し間隔を調整する */
   }
   /* ここで改行を出力する */
 }
 ================================================
 のような処理になると思います。

※GUIアプリの場合でも、基本的に月毎に表示位置をずらすようにすれば良い
 と思います。

以上です。

こんにちは。

前提として、作成するプログラムがコンソールアプリで、コンソール画面
にカレンダーを表示する場合ですが。。。
※以下は、あくまで一例です。

■縦方向に並べて表示する場合
※こちらは、#1さんの言われるように、単純に作成済みの1ヶ月カレンダー
 表示プログラムを、3回呼ぶだけで良いと思います。

1)既に作成済みのカレンダー表示を行うプログラムを関数化します。
  例)
  void DispMonth( int nYear, int nMonth );
   int nYear  : カレンダーの年
   int nMonth : カレン...続きを読む

Q西暦・月からカレンダーを表示

問題文
西暦・月を入力してカレンダーを表示するプログラムを作成せよ。

プログラム全体のことを考える。プログラムの流れとしては、つぎのようになるであろう。
 (1)変数の宣言: プログラムの中で使う変数や配列等をすべてここに集めておく。        
 (2)入力: キーボードから、西暦年の値を読み取る ← scanf( ) 関数
 1月から12月まで、以下を繰り返す。
 (3)カレンダーの年・月の表示: (例えば、2008年1月 と表示)
 (4)各曜日名の表示: 「日 月 火 水 木 金 土」と表示
 (5)月の日数の算出: 月の最後の日を計算しておく。(*1~12月以外では誤りとすること)
 (6)曜日の算出: 月の初めの日(ついたち)の曜日をツェラー公式で計算しておく。
 (7)空列の表示: ついたちの前の空白部分を表示する ← for文 を利用。
 (8)各日の表示: 月の各日を順に表示していく ← for文を利用
         (土曜の後に改行を入れる)

#include <stdio.h>

int leapYear(int year)
{
if (year%400==0||(year%4==0 && year%100!=0))
{
return 1;
}
else
{
return 0;
}
}
int main(void)
{

int d,year,m,i;
int day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /*1~12月までの各月の日数*/

printf("西暦を入力してください:");
scanf("%d",&year);
printf("月を入力してください:");
scanf("%d",&m);
if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)/*1~12月以外で日数を出そうとした場合*/
{
printf("入力が誤っています。やりなおしてください。\n");
}
else{
if (leapYear(year)==1)/*閏年の場合*/
{
printf("%d年は閏年です。\n",year);
day[1] +=1;
}

else/*閏年でない場合*/
{
printf("%d年は閏年ではありません。\n",year);
}
i = (year+year/4 -year/100 +year/400 + ( 13*m+8 )/5 + 1) % 7; /*西暦~年・1~12月の1日の曜日について考える*/

printf("日 月 火 水 木 金 土\n");

(7)・・・
(8)・・・

}
return 0;
}

手順に沿ってやっていく課題なのですが(7)、(8)の部分の表現の仕方が良く分かりません。(求めた月の日数をカレンダー形式に表示する方法・1日の前に空白を入れる等)
過去の質問も見たのですが、いまいち理解できず・・・orz
どなたかご教授お願いできないでしょうか・・・。

問題文
西暦・月を入力してカレンダーを表示するプログラムを作成せよ。

プログラム全体のことを考える。プログラムの流れとしては、つぎのようになるであろう。
 (1)変数の宣言: プログラムの中で使う変数や配列等をすべてここに集めておく。        
 (2)入力: キーボードから、西暦年の値を読み取る ← scanf( ) 関数
 1月から12月まで、以下を繰り返す。
 (3)カレンダーの年・月の表示: (例えば、2008年1月 と表示)
 (4)各曜日名の表示: 「日 月 火 水 木 金 土」と表示
 (...続きを読む

Aベストアンサー

>(7)、(8)の部分の表現の仕方が良く分かりません。

 難しく考えていませんか。

 ・朔日の前に空白
 ・土曜( 6 )出力後改行

 だけですよね。
-------------------------------------
  i01Youbi = Zeller( year, m ); // 0-6

  for( i = 0; i < i01Youbi; i++ ) printf( "___" ); // 朔日の前に空白3つ▼×必要分(投稿上 _ としています)

  for( i = 1; i <= day[ m - 1 ]; i++ ){

    printf( "%3d", i ); // 3桁▲上と同じに

    if( 6 == ( ( i - 1 + i01Youbi ) % 7 ) ) printf( "\n" ); // 土曜出力後改行
  }
  printf( "\n" );
 (インデントに全角空白使用)
-------------------------------------
>day[ 1 ] += 1; 確かに 29 になるのですが、

 day[ 1 ] = 29; とした方が・・(今回はOKですが・・やがて?)。

>(7)、(8)の部分の表現の仕方が良く分かりません。

 難しく考えていませんか。

 ・朔日の前に空白
 ・土曜( 6 )出力後改行

 だけですよね。
-------------------------------------
  i01Youbi = Zeller( year, m ); // 0-6

  for( i = 0; i < i01Youbi; i++ ) printf( "___" ); // 朔日の前に空白3つ▼×必要分(投稿上 _ としています)

  for( i = 1; i <= day[ m - 1 ]; i++ ){

    printf( "%3d", i ); // 3桁▲上と同じに

    if( 6 == ( ( i - 1 + i01Youbi...続きを読む

Q日付から曜日を求めたい

Windows APIでプログラミングしています。時間のデータはSYSTEMTIMEを使ってます。

日付(wYear, wMonth, wDay)のみの情報から、曜日(wDayOfWeek)を求めたいのですが、どのような方法があるでしょうか?曜日を求めるAPI関数は存在しますか?

Aベストアンサー

曜日が入っていない状態のSYSTEMTIMEからSystemTimeToFileTimeでFILETIMEに変換し、
FileTimeToSystemTimeでSYSTEMTIMEに戻せば、曜日が入った状態になります。

Q万年カレンダーのC言語プログラムを教えてください

西暦年と月を入力すると、その年月のカレンダーが出てくる万年カレンダーのC言語プログラムを教えてください!お願いします!

Aベストアンサー

>ありがとうございます。さっそくプログラムを動かしてみました。でも第一週と第二週の日付がうまくつながっていないです。これはどうしてでしょうか?

ごめんなさい。
htmlの半角スペースを連続して書くと1個にされてしまう事を忘れていました。
下から7行目の
printf(" ");
の半角スペース1個は半角スペース3個にしてください。

Q日数を計算する方法

以下のようにして変数の配列を使って、
月の日数を格納しています。
int mon[12]={31,28,31,30,31,30,31,31,30,31,30,31};

これを使って、
元旦から入力された月日の日数を計算したいのですが
どの様にすればいいですか?

例えば、

4月5日の場合は、
1月 31日
2月 28日
3月 31日
4月 5日

なので「95日」

----------------
途中までのプログラム
#include<stdio.h>

main(void)
{int yy, mm, dd;
int mon[12]={31,28,31,30,31,30,31,31,30,31,30,31};

printf( "西暦を入力しなさい" );
scanf( "%d", &yy );
printf( "月を入力しなさい" );
scanf( "%d", &mm );
printf( "日を入力しなさい" );
scanf( "%d", &dd );

/* うるう年判定 */
if (((yy%4==0)&&(yy%100!=0))||(yy%400==0)) mon[1]=29; else mon[1]=28;

以下のようにして変数の配列を使って、
月の日数を格納しています。
int mon[12]={31,28,31,30,31,30,31,31,30,31,30,31};

これを使って、
元旦から入力された月日の日数を計算したいのですが
どの様にすればいいですか?

例えば、

4月5日の場合は、
1月 31日
2月 28日
3月 31日
4月 5日

なので「95日」

----------------
途中までのプログラム
#include<stdio.h>

main(void)
{int yy, mm, dd;
int mon[12]={31,28,31,30,31,30,31,31,30,31,30,...続きを読む

Aベストアンサー

要するに「配列にあるデータの合計を求める」のと同じなんだから, ふつうに考えれば for 文で足し込んでいくんでしょ~ね.

Q入力した日は何曜日か

入力した日が何曜日か出したいのですがどうしても曜日が一日ずれてしまいます。どこが悪いのかアドバイスお願いします

#include<stdio.h>

int main() {

int iyear,imonths,iday;
int sum,i;
int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
char*cweek[7] = {"日","月","火","水","木","金","土"};

sum =0;
printf ("input (e.g. ****/**/**)\n>>");
scanf ("%d/%d/%d",&iyear,&imonths,&iday);

/*閏年の判定*/
for(i=1;i<year;i++){
if((year%4==0)&&((year%100!=0))||(year%400==0)){
sum++;
i++;
}
year--;

/*前月までの日数*/
for (i =0; i < imonths-1; i++) {
sum += m_array[i];
}

year++;

sum=sum+day;
//曜日の出力
printf("%s曜日",cweek[sum%7]);
return 0;
}
}

入力した日が何曜日か出したいのですがどうしても曜日が一日ずれてしまいます。どこが悪いのかアドバイスお願いします

#include<stdio.h>

int main() {

int iyear,imonths,iday;
int sum,i;
int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
char*cweek[7] = {"日","月","火","水","木","金","土"};

sum =0;
printf ("input (e.g. ****/**/**)\n>>");
scanf ("%d/%d/%d",&iyear,&imonths,&iday);

/*閏年の判定*/
for(i=1;i<year;i++){
if((year%4==0)&&((ye...続きを読む

Aベストアンサー

私も Zeller の公式をお勧めしますが, このプログラムだと「少なくとも閏年の 2月28日までか 3月1日以降かのいずれかはおかしくなる」はずです. 曜日を出力する直前で sum の値を見てみればわかると思いますが, 例えば 2008/2/29 と 2008/3/1 が同じ値になりますね.

Q日付の差分の求め方(日、分)

NT4WS+VC++6.0 Win32コンソールアプリで作ってます。
現在int型で
year1,month1,day1 year2,month2,day2
の様に、1と2それぞれ年月日を持っています。
(year2/month2/day2) - (year1/month1/day1)
と言った感じで1と2の差が何日かを求めたいのです。
VBで言うDateDiffみたいなことがやりたいのです。
よろしくお願いします。

Aベストアンサー

ANSI の範囲で考えると、difftime() という関数が利用できます。difftime() が
扱えるのは time_t 型で表した時刻なのですが、整数で表された年月日などを、この
time_t 型に変換する mktime() という関数と組合わせて使います。

こういうふうに使います。

#include <time.h>
#include <stdio.h>

int main()
{
  int year1, month1, day1;
  int year2, month2, day2;
  year1 = 2001; month1 = 12; day1 = 30;
  year2 = 2002; month2 = 1; day2 = 16;

  {
    struct tm d;
    time_t t1, t2;
    double diff;

    // 開始・終了日を time_t 型の変数にする
    memset(&d, 0, sizeof(d));
    d.tm_year = year1 - 1900;
    d.tm_mon = month1 - 1;
    d.tm_mday = day1;
    t1 = mktime(&d);
    d.tm_year = year2 - 1900;
    d.tm_mon = month2 - 1;
    d.tm_mday = day2;
    t2 = mktime(&d);

    diff = difftime(t2, t1);

    // difftime() の返り値は「秒」で double 型
    // ÷60÷60÷24 で日数にして、+0.5 は四捨五入のため
    printf("%d 日差.\n", (int)(diff / 60 / 60 / 24 + 0.5));
  }

  return 0;
}

ANSI の範囲で考えると、difftime() という関数が利用できます。difftime() が
扱えるのは time_t 型で表した時刻なのですが、整数で表された年月日などを、この
time_t 型に変換する mktime() という関数と組合わせて使います。

こういうふうに使います。

#include <time.h>
#include <stdio.h>

int main()
{
  int year1, month1, day1;
  int year2, month2, day2;
  year1 = 2001; month1 = 12; day1 = 30;
  year2 = 2002; month2 = 1; day2 = 16;

  {
    struct tm d;
...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング