ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

C言語コミュの[課題]8桁の8進数を10進数に変換する関数を作るプログラム

  • mixiチェック
  • このエントリーをはてなブックマークに追加
問文)
 引数octで指定された文字列が表す8桁の8進数を10進数に変換する関数
int octtodec(char oct[8])
を作成し、負数が入力されるまで、入力された8進数を10進数に変換して出力するプログラムを作成せよ。入力された文字列が8進数でなかった場合、エラーを出力して再度入力を促すこと。

(例)
user>a.out
Input number (Oct) : 1234
oct:1234 → dec:668
Input number (Oct) : 9876
Error: 9876 is NOT an oct number.
Input number (Oct) : -1
bye...
user>


引数でchar型で渡すので標準入力もchar型にしているのですが、そうすると入力された文字列が負数かどうかという判断ができなくなってしまうので・・・つまり最初っから突っかかってます。
何かいい方法がありましたら教えてください。

コメント(11)

すみません、コミュTOPの注意点を最後まで読まず最後に3行ほどコメント入れちゃいました。
もしダメでしたらコミュ管理者さん、お手数ですが削除お願いします。
文字列を操作する時はまずstr〜系の関数を考慮すると良いでしょう。
今回はstrtolを使っていいなら一発ですね。

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

int
octtodec(char oct[8])
{
    return strtol(oct, NULL, 8);
}

int
main(void)
{
    for (;;) {
        char buf[8];
        int val;

        printf("Input number (Oct) : ");
        fgets(buf, sizeof(buf), stdin);
        if ((val = octtodec(buf)) < 0) {
            printf("bye...\n");
            break;
        }
        buf[strlen(buf) - 1] = '\0'; /* remove '\n' */
        printf("oct: %s -> dec: %d\n", buf, val);
    }

    return EXIT_SUCCESS;
}

余談ですが、.をpathに加えると/tmpなど自分以外の利用者が読み書きするディレクトリでコマンドを打ったときに自分の権限で予期しないコマンドが実行されるかも知れません。
さっきは8進数でなかった場合の判定を入れ忘れたのでもう一度。

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

int
octtodec(char oct[8])
{
    return strtol(oct, NULL, 8);
}

bool
is_oct(char *str)
{    /* strtol(3) returns 0 if given value is 0, or given value is wrong. */
    return (str[0] == '0' || strtol(str, NULL, 8) != 0);
}

int
main(void)
{
    for (;;) {
        char buf[8];
        int val;

        for (;;) {
            printf("Input number (Oct) : ");
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf) - 1] = '\0'; /* remove '\n' */
            if (!is_oct(buf)) {
                printf("Error: %s is NOT an oct number.\n",
                    buf);
                continue;
            } else
                break;
        }
        if ((val = octtodec(buf)) < 0) {
            printf("bye...\n");
            break;
        }
        printf("oct: %s -> dec: %d\n", buf, val);
    }

    return EXIT_SUCCESS;
}
さらに、8進数判定を分ける必要は無いので、こんな感じ。
EINVALが何かはstrtolのマニュアルを参照してくださいな。

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

int
octtodec(char oct[8])
{
    return strtol(oct, NULL, 8);
}

int
main(void)
{
    for (;;) {
        char buf[8];
        int val;

        printf("Input number (Oct) : ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = '\0'; /* remove '\n' */
        val = octtodec(buf);
        if (val == 0 && errno == EINVAL) {
            printf("Error: %s is NOT an oct number.\n",
                buf);
            continue;
        } else if (val < 0) {
            printf("bye...\n");
            break;
        } else
            printf("oct: %s -> dec: %d\n", buf, val);
    }

    return EXIT_SUCCESS;
}
おしょーさん、ありがとうございます。
でもこのプログラムでやると8以上の数字や文字が入力されたときにエラー表示にならない気がするんですがどうでしょうか?
>ゐがさん
ここに投稿させて貰う前にatoiでやってみましたがエラーをはかれて失敗してしまったので断念しました。
> でもこのプログラムでやると8以上の数字や文字が入力されたときに
> エラー表示にならない気がするんですがどうでしょうか?
この8とは8桁のことですよね?
入力桁数が8桁でない場合にエラーにするとは書いていなかったので
何もしてませんでした。

これでどうでしょう?

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

int
octtodec(char oct[8])
{
    return strtol(oct, NULL, 8);
}

int
main(void)
{
    for (;;) {
        char buf[8 + 1 + 1]; /* data + canary + null */
        int val;

        printf("Input number (Oct) : ");
        buf[sizeof(buf) - 2] = '\0'; /* set a canary value */
        fgets(buf, sizeof(buf), stdin);
        /* Although the canary dead, still charactors remain. */
        if ((buf[sizeof(buf) - 2] != '\0') &&
            (buf[sizeof(buf) - 2] != '\n')) {
            char c;
            printf("Error: %s", buf);
            for (c = buf[sizeof(buf) - 2]; c != '\n';
                    c = getchar())
                printf("%c", c);
            printf(" is NOT an acceptable length.\n");
            continue;
        }
        buf[strlen(buf) - 1] = '\0'; /* remove '\n' */
        val = octtodec(buf);
        if (val == 0 && errno == EINVAL) {
            printf("Error: %s is NOT an oct number.\n",
                buf);
            continue;
        } else if (val < 0) {
            printf("bye...\n");
            break;
        } else
            printf("oct: %s -> dec: %d\n", buf, val);
    }

    return EXIT_SUCCESS;
}

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

C言語 更新情報

C言語のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。