Thinkers'Studio
JavaとC言語の自習ツール
西暦年を和暦に変換するプログラム例(文字列を返す関数)

 関数の戻り値として、文字列を返すサンプルです。
 西暦年を引数に渡すと、"平成○年" などの和暦の文字列を返す関数をつくります。

【 西暦年を和暦に変換するプログラム例(文字列を返す関数) 】
 明治以降を対象とします。また、日付までの厳密な対応はしていません。
 (たとえば 1989年は1月7日までは昭和ですが、ここでは平成元年とします)
#include <stdio.h>
#include <string.h>
#define MEIJI  1868
#define TAISHO 1912
#define SHOWA  1926
#define HEISEI 1989

char *wareki( int y )
{
    char gg[8];
    static char str[24];

    if( y >= HEISEI ) {
        strcpy( gg, "平成" ); y = y-HEISEI+1;
    } else if( y >= SHOWA ) {
        strcpy( gg, "昭和" ); y = y-SHOWA+1;
    } else if( y >= TAISHO ) {
        strcpy( gg, "大正" ); y = y-TAISHO+1;
    } else if( y >= MEIJI ) {
        strcpy( gg, "明治" ); y = y-MEIJI+1;
    } else {
        sprintf( str, "(明治以前は未対応)" );
        return str;
    }
    if( y == 1 ) sprintf( str, "%s元年", gg );
    else sprintf( str, "%s%d年", gg, y );
    return str;
}

main()
{
    int years[] = { 1192, 1925, 1986, 1989, 2013 };
    int i;

    for( i = 0; i < 5; i++ ) {
        printf( "西暦%d年 : ", years[i] );
        printf( "%s\n", wareki( years[i] ) );
    }
}
 実行結果
西暦1192年 : (明治以前は未対応)
西暦1925年 : 大正14年
西暦1986年 : 昭和61年
西暦1989年 : 平成元年
西暦2013年 : 平成25年

 西暦年 y を各元号の開始年と比較して、どの元号かを判定します。
 値の大きい「平成」から比較し、else if で範囲を狭めていくと、終了年のチェックが要りません。
 和暦での年は、y-その元号の開始年+1 です。y は値渡しなので、関数内で書き換えても元の値は変わりません。

文字列を戻り値で返す

static変数のアドレスを返す

 C言語で文字列を戻り値として返す場合、文字列へのポインタを返すようにします。
 そして、一般的な方法としては static をつけて宣言した char配列を用意し、返したい文字列を設定します。 return 配列名 として、その配列の先頭要素のアドレスを返します。

static をつけないと

 上のプログラムで static char str[12]; の static を取ると、コンパイルで警告が出ます。関数内で宣言した変数はその関数を出ると消えてしまうからです。 static をつけて静的変数とすると、プログラム実行中は値が保持されます。

グローバル変数を使う

 別の方法として、グローバル変数の char配列を用意し、そのアドレスを返すこともできます。
 グローバル変数は静的変数ですから、結局は「有効なデータのアドレスを返すようにする」ということです。

(今回のクイズです)
 上のプログラムで、define している元号の開始年を enum で書くには、どのようにすればよいでしょうか?
   (答えは、次回のC言語の Tips で ・・・)

[ 関連記事 ] 和暦→西暦変換


前回 クイズはありませんでした)