Thinkers'Studio
JavaとC言語の自習ツール
和暦を西暦年に変換するプログラム例

 前回の西暦年→和暦の逆で、和暦→西暦年の変換プログラムです。
 関数引数charへのポインタを受け取り、int の戻り値で西暦年を返す例です。

【 和暦を西暦年に変換するプログラム例 】
 和暦の指定は、"H25" のように1文字目を元号のアルファベットとします。 明治以降の M, T, S, H のいずれかです。
 それ以外はエラーとして -1 を返します。
#include <stdio.h>
#include <ctype.h>
enum gengo { MEIJI=1868, TAISHO=1912, SHOWA=1926, HEISEI=1989 };

int toSeireki( char *wareki )
{
    int sty, year;

    // 1文字目の元号に対応する開始西暦年をstyへ
    switch( toupper(wareki[0]) ) {
    case 'M' : sty = MEIJI;  break;
    case 'T' : sty = TAISHO; break;
    case 'S' : sty = SHOWA;  break;
    case 'H' : sty = HEISEI; break;
    default: return -1;
    }
    // 元号の後ろから年を取り出す
    if( sscanf( &wareki[1], "%d", &year ) != 1 ) return -2;
    // 西暦で何年かを返す
    return (sty + year - 1);
}

main()
{
    char wyears[][6] = { "H25", "S35", "W34", "T1", "1999" };
    int i;
    for( i = 0; i < 5; i++ ) {
        printf( "%d\n", toSeireki( wyears[i] ) );
    }
}
 実行結果
2013
1960
-1
1912
-1
 引数で渡された char *wareki の内容を参照するところが2箇所あります。
   toupper(wareki[0])                ・・・ 先頭の1文字の内容を参照
   sscanf( &wareki[1], "%d", &year ) ・・・ 文字列の2文字目から%dの書式で入力
 toupper は、元号を小文字で指定した場合もOKとするために使っています。

列挙定数 enum

 元号の開始年を定義するのに、前回は define を使いましたが、ここでは enum としました。コンパクトで、元号リストであることが明確です。 enum は列挙定数と呼ばれ、整数定数のリストに名前をつけるものです。
 上のプログラムではそれぞれの定数値を指定していますが、下記のように値を指定しなくても構いません。その場合、先頭は自動的に 0 となり、それ以降 1ずつ大きい値が割り当てられます。
  enum week { SUN, MON, TUE, WED, THU, FRI, SAT }; //SUNが0, MONは1, TUEは2 ・・・
 一部だけ値を指定することもできます。
  enum polygon { TRI=3, SQR, PEN, HEX, HEP }; //3以降, 4, 5, 6, 7

(今回のクイズです)
 上のプログラムは、「先頭が M,T,S,H 以外のときは、すべて -1 のエラー」という仕様なので、もし wareki に西暦年を渡してもエラーになります。 これを、西暦で指定されたらそのまま返すようにするには、どうすればよいでしょうか?
  【変更後の仕様】
   「先頭が M,T,S,H 以外のとき、wareki が整数値として読めればそれを西暦年として返す。読めなければ -1 のエラー」
  【修正箇所】 default: に処理を追加してください。

   (答えは、次回のC言語の Tips で ・・・)

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

前回のクイズの答え: (前回の問題を見る
 答えは、上のプログラムの 3行目に書かれています。