ページ 11

和暦変換

Posted: 2015年9月18日(金) 22:39
by monsutonton
引数として生年月日を受け取り、和暦変換する。和暦は昭和から平成でよい。年号に注意する。昭和以前、2015年以降ならmain関数で判定し、エラーを出力する。

プログラムを作りましたが、間違っているようです。問題と違うのはわかりましたが、どうすればよいですか?

コード:

#include <stdio.h>
void print_wareki(int year,int month,int day);

int main(void)
{
	int year;
	int month;
	int day;
	int result;
	
	printf("西暦を入力してください。\n");
	scanf("%d",&year);
	
	printf("月を入力してください。\n");
	scanf("%d",&month);
	
	printf("日を入力してください。\n");
	scanf("%d",&day);
	
	if(year < 1927 || year == 1926 && month <= 12 && day <=24 || year > 2014 
		|| month > 12 || month < 1 || day > 31 || day < 1 || month == 2 && day > 28
		|| month == 4 && day > 30 || month == 6 && day > 30 || month == 9 && day > 30 
		|| month == 11 && day > 30)
	{
		printf("エラー\n");
	}
	else
	{
		result = print_wareki(year,month,day);
	}
	
	return 0;
}

void print_wareki(int year,int month,int day)
{
	int result;
	
	if(year >= 1926 && year <= 1989)
	{
		if(year < 1989)
		{
			result = year-1925;
			printf("昭和%d年%d月%d日です。\n",year,month,day);
		}
		else if(year == 1989)
		{
			result = year-1925;
			printf("昭和%d年%d月%d日です。\n",year,month,day);
		}
		else if(year == 1989)
		{
			result = year-1988;
			printf("平成%d年%d月%d日です。\n",year,month,day);
		}
	}
	else if(year >= 1990)
	{
		result = year-1988;
		printf("平成%d年%d月%d日です。\n",year,month,day);
	}
}

Re: 和暦変換

Posted: 2015年9月19日(土) 00:22
by box
少なくとも、
monsutonton さんが書きました:

コード:

void print_wareki(int year,int month,int day);
戻り値がない、と言っている関数について
monsutonton さんが書きました:

コード:

		result = print_wareki(year,month,day);
これはおかしいでしょう。しかも、resultに代入した結果をその後で使っていませんし。
コンパイルが通ってないのではないですか?

Re: 和暦変換

Posted: 2015年9月19日(土) 00:29
by box
あと、エラーチェックとか昭和・平成の判断なんかはprint_warekiへ持っていく方が
いいような気もします。

Re: 和暦変換

Posted: 2015年9月19日(土) 04:07
by かずま
月日や閏年も考慮しないといけないのでは?

コード:

#include <stdio.h>

struct { int start; const char *name; } s[4] = {
    { 19890108, "平成" },
    { 19261225, "昭和" },
    { 19120730, "大正" },
    { 18680125, "明治" },
};

void print_wareki(int year, int month, int day)
{
    int i, d = year * 10000 + month * 100 + day;
    for (i = 0; i < 4 && d < s[i].start; i++) ;
    if (i < 4)
        printf("%s%d年 %d月 %d日\n",
            s[i].name, year - s[i].start/10000 + 1, month, day);
}

int last_day(int year, int month)
{
    static int t[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    if (month != 2) return t[month - 1];
    return 28 + (year%4==0 && (year%100 || year%400==0));
}

int main(void)
{
    int year, month, day;
    while (1) {
        printf("input year month day: ");
        if (scanf("%d%d%d", &year, &month, &day) != 3) break;
        if (year < 1868 || month < 1 || month > 12 || day < 1 ||
                day > last_day(year, month))
            printf("エラー\n");
        else 
            print_wareki(year, month, day);
    }
    return 0;
}
実行結果

コード:

input year month day: 1989 1 7
昭和64年 1月 7日
input year month day: 1989 1 8
平成1年 1月 8日
input year month day: .

Re: 和暦変換

Posted: 2015年9月19日(土) 15:34
by かずま
私が参考にしてほしいと思って書いたプログラムは、
昭和より前や 2015以降をエラーにするということはしていないので
課題の解答ではありません。
日付の比較が面倒なので、一つの方法を提案してみたつもりなんですが、
やはり解説なしではその意図を読み取ってもらえないと思い直して、
ちょっと説明してみます。

昭和は 1926年12月25日から 1989年1月7日までです。
質問者のプログラムでは昭和の前をエラーにしようと思って、

コード:

  if(year < 1927 || year == 1926 && month <= 12 && day <=24 || year > 2014
と書いていますが、これだと year < 1927 により、
1926年12月25~31日がエラーになってしまいます。
year > 1926 にすると、ちょっと改善されますが、
year == 1926 && month <= 12 && day <=24 では、
1926年11月25~30日がエラーになりません。

コード:

        else if(year == 1989)
        {
            result = year-1925;
            printf("昭和%d年%d月%d日です。\n",year,month,day);
        }
        else if(year == 1989)
        {
            result = year-1988;
            printf("平成%d年%d月%d日です。\n",year,month,day);
        }
これも目を疑うコードですよね。平成は絶対に表示されません。

日付の比較は、普通は次のようにします。

コード:

    if (year < 1926 ||
            year == 1926 && (month < 12 || month == 12 && day < 25))
        printf("エラー\n");
    else if (year < 1989 ||
            year == 1989 && month == 1 && month < 8)
        printf("昭和%d年 %d月 %d日です。\n", year - 1925, month, day);
    else if (year < 2015)
        printf("平成%d年 %d月 %d日です。\n", year - 1988, month, day);
    else
        printf("エラー\n");
でも、次のようにすると分かりやすくなりますよ、という提案でした。

コード:

	int d = year * 10000 + month * 100 + day;
    if (d < 19261225)
		printf("エラー\n");
	else if (d < 19890108)
		printf("昭和%d年 %d月 %d日です。\n", year - 1925, month, day);
	else if (d < 20150101)
		printf("平成%d年 %d月 %d日です。\n", year - 1988, month, day);
	else
		printf("エラー\n");

Re: 和暦変換

Posted: 2015年9月19日(土) 18:05
by monsutonton
返答ありがとうございます。いろいろ試行しましたが、できません。そもそも使い方がおかしいです。
指摘お願いします。また、問題とあってますか?

コード:

#include <stdio.h>
void print_wareki(int year,int month,int day);

int main(void)
{   
	 int result;
	
	 result(year,month,day);
	
	 if (year < 1926 ||year == 1926 && (month < 12 || month == 12 && day < 25))
	 {
	 	printf("エラー\n");
	 }
     else if (year < 1989 ||year == 1989 && month == 1 && month < 8)
     {
        printf("昭和%d年 %d月 %d日です。\n", year - 1925, month, day);
     }
     else if (year < 2015)
     {
        printf("平成%d年 %d月 %d日です。\n", year - 1988, month, day);
     }
     else
     {
        printf("エラー\n");
     }
	
	return 0;
}

void print_wareki(int year,int month,int day)
{
	int year;
	int month;
	int day;
	int result;
	
	printf("西暦を入力してください。\n");
	scanf("%d",&year);
	
	printf("月を入力してください。\n");
	scanf("%d",&month);
	
	printf("日を入力してください。\n");
	scanf("%d",&day);
	 
	result(year,month,day);
	
	return result;
}  

Re: 和暦変換

Posted: 2015年9月19日(土) 20:38
by box
こんなコードが何かの役に立つとはあまり思いませんが、
変数の定義・関数の定義・引数・戻り値
について再確認する参考になるとしたらうれしいです。

コード:

#include <stdio.h>

int add1(int m, int n)
{
    return m + n;
}

void add2(int m, int n)
{
    printf("2数の和は%d\n", m + n);
}

int main(void)
{
    int a, b;

    printf("2個の整数を、例えば12 -34のように入力してください\n");
    scanf("%d%d", &a, &b);
    printf("2数の和は%d\n", add1(a, b));
    add2(a, b);
    return 0;
}

Re: 和暦変換

Posted: 2015年9月19日(土) 21:35
by monsutonton
いかがですか?

コード:

#include <stdio.h>
void print_wareki(int year,int month,int day);
 
int main(void)
{   
     int result;
    
     result=print_wareki(year,month,day);
    
     if (year < 1926 ||year == 1926 && (month < 12 || month == 12 && day < 25))
     {
        printf("エラー\n");
     }
     else if (year < 1989 ||year == 1989 && month == 1 && month < 8)
     {
        printf("昭和%d年 %d月 %d日です。\n", year - 1925, month, day);
     }
     else if (year < 2015)
     {
        printf("平成%d年 %d月 %d日です。\n", year - 1988, month, day);
     }
     else
     {
        printf("エラー\n");
     }
    
}
 
void print_wareki(int year,int month,int day)
{
    int year;
    int month;
    int day;
    int result;
    
    printf("西暦を入力してください。\n");
    scanf("%d",&year);
    
    printf("月を入力してください。\n");
    scanf("%d",&month);
    
    printf("日を入力してください。\n");
    scanf("%d",&day);
     
    result(year,month,day);
    
    return 0;
}

Re: 和暦変換

Posted: 2015年9月20日(日) 00:10
by box
monsutonton さんが書きました:いかがですか?
何ともコメントのしようがないです。
とりあえず、コンパイルが通るコードを書いてみてください。

Re: 和暦変換

Posted: 2015年9月20日(日) 22:23
by monsutonton
とりあえず、勉強して実行までやりました。
条件の指摘をお願いします。

コード:

#include <stdio.h>
void print_wareki(int year,int month,int day);
int main(void)
{
	int year;
    int month;
    int day;
    
    printf("西暦を入力してください。\n");
    scanf("%d",&year);
    
    printf("月を入力してください。\n");
    scanf("%d",&month);
    
    printf("日を入力してください。\n");
    scanf("%d",&day);
	
	if (year < 1926 || year == 1926 && (month < 12 || month == 12 && day < 25) || 2015 >year)
    {
      	printf("エラー\n");
    }
	else
	{
		print_wareki(year,month,day);
	}
	return 0;
}

void print_wareki(int year,int month,int day)
{
    if (year < 1989 || year == 1989 && month == 1 && month < 8)
    {
        printf("昭和%d年 %d月 %d日です。\n", year - 1925, month, day);
    }
    else if (year < 2015)
    {
        printf("平成%d年 %d月 %d日です。\n", year - 1988, month, day);
    }
}

Re: 和暦変換

Posted: 2015年9月20日(日) 22:43
by box
monsutonton さんが書きました: 条件の指摘をお願いします。
自分で実行して、テストしていますか?
monsutonton さんが書きました:

コード:

	if (year < 1926 || year == 1926 && (month < 12 || month == 12 && day < 25) || 2015 >year)
去年(2014年)の日付や今年(2015年)の日付を入れて実行してみてください。
もともとの仕様どおりに動きますか?