c言語和暦から西暦

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
puma

c言語和暦から西暦

#1

投稿記事 by puma » 7年前

c言語で次のような実行例になるプログラムを作っています。
実行例
./a.out
Input Wareki: H29
Year: 2017
% ./a.out
Input Wareki: S52
Year: 1977
% ./a.out
Input Wareki: M21
Year: 1888

文字列をintがたの整数にして返す関数はできているのですがint main()の途中から話kらなくなってしまったので、教えてくださいお願いします。
条件は次のようになってます。
標準入力から和暦で H29(平成29年の場合)などと入力すると、それが西暦何年かを計算して表示するプログラムを作成しなさい。 入力は1文字目がアルファベットで H, S, T, M がそれぞれ平成、昭和、大正、明治を表しており、数字との間にスペースなどの区切りは無いため、ひと続きの文字列として読み込む。 文字列から数値への変換には問題1で作成した関数 myatoi をそのままコピーして使用し、main関数のみを新たに作成すること。

コード:

 
#include <stdio.h>
int myatoi(char *);
int main()
{
  int a,i;
  char w[50];
printf("Input Wareki: ");
scanf("%49s",w);
 a=myatoi(w); 



return 0;
}
int myatoi(char *p)
{
  int sign = 1;
int ret = 0;

/* スペースを読み飛ばす */
while (*p == ' ') p++;

/* 「-」「+」の処理 */
if (*p == '-') {
sign = -1;
p++;
} else if (*p == '+') {
p++;
}

/* 数字の読み取り */
for (;*p != '\0';p++) {
if (*p>='0' && *p<='9') {
ret *= 10;
ret += *p - '0';
} else {
break;
}
}

return ret * sign;
}



 



 

box
記事: 2002
登録日時: 13年前

Re: c言語和暦から西暦

#2

投稿記事 by box » 7年前

puma さんが書きました: 文字列をintがたの整数にして返す関数はできているのですが
元号をローマ字表記したときの先頭文字からその元号が始まったり(あるいは終わったり)する西暦の取得は?
puma さんが書きました: 標準入力から和暦で H29(平成29年の場合)などと入力すると、それが西暦何年かを計算して表示するプログラムを作成しなさい。 入力は1文字目がアルファベットで H, S, T, M がそれぞれ平成、昭和、大正、明治を表しており、数字との間にスペースなどの区切りは無いため、ひと続きの文字列として読み込む。 文字列から数値への変換には問題1で作成した関数 myatoi をそのままコピーして使用し、main関数のみを新たに作成すること。
そのままコピーっていっても、さすがに、先頭文字がHならば平成(西暦1989~)、Sならば昭和(西暦1926~1989)、Tならば大正(西暦1912~1926)、Mならば明治(西暦1968~1912)という
判断をする処理は必要でしょう。そう思いませんか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: c言語和暦から西暦

#3

投稿記事 by box » 7年前

あと、仕様上問題になりそうなのは、M46とかT16とかS65とか、実際にはなかった年を入力したときにエラーとするのか
便宜上出力するのか(M46ならば1913、T16ならば1927、S65ならば1990)といったところでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: c言語和暦から西暦

#4

投稿記事 by みけCAT » 7年前

box さんが書きました:
puma さんが書きました: 文字列をintがたの整数にして返す関数はできているのですが
元号をローマ字表記したときの先頭文字からその元号が始まったり(あるいは終わったり)する西暦の取得は?
「main関数のみを新たに作成すること」なので、独立した関数にすることはできなそうですね。
box さんが書きました:そのままコピーっていっても、さすがに、先頭文字がHならば平成(西暦1989~)、Sならば昭和(西暦1926~1989)、Tならば大正(西暦1912~1926)、Mならば明治(西暦1968~1912)という
判断をする処理は必要でしょう。そう思いませんか?
その判断をする処理はmain関数に書けばいいでしょう。
何も制約がなければ別の関数にするべきかもしれませんが、「main関数のみを新たに作成すること」という条件があるので。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: c言語和暦から西暦

#5

投稿記事 by box » 7年前

こんな感じ?
元のコードのインデントがあまりにグッチャングッチャンだったので自分なりに直しておきました。なお、
box さんが書きました:あと、仕様上問題になりそうなのは、M46とかT16とかS65とか、実際にはなかった年を入力したときにエラーとするのか
便宜上出力するのか(M46ならば1913、T16ならば1927、S65ならば1990)といったところでしょうか。
ここは後者の策を採りました。

コード:

#include <stdio.h>

int myatoi(char *p);

int main(void)
{
    int y, n;
    char w[50];

    printf("Input Wareki: ");
    scanf("%49s", w);
    switch (w[0]) {
    case 'H': case 'h':
        y = 1988;
        break;
    case 'S': case 's':
        y = 1925;
        break;
    case 'T': case 't':
        y = 1911;
        break;
    case 'M': case 'm':
        y = 1867;
        break;
    default:
        fprintf(stderr, "Invalid Gengou\n");
        return 1;
    }
    if ((n = myatoi(&w[1])) <= 0) {
        fprintf(stderr, "Invalid Year\n");
        return 1;
    }
    printf("Year: %d\n", y + n);
    return 0;
}

int myatoi(char *p)
{
    int sign = 1;
    int ret = 0;

    /* スペースを読み飛ばす */
    while (*p == ' ') p++;

    /* 「-」「+」の処理 */
    if (*p == '-') {
        sign = -1;
        p++;
    } else if (*p == '+') {
        p++;
    }

    /* 数字の読み取り */
    for (; *p != '\0'; p++) {
        if (*p >= '0' && *p <= '9') {
            ret *= 10;
            ret += *p - '0';
        } else {
            break;
        }
    }
    return ret * sign;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る