41章 scanfの詳細

http://www.geocities.jp/ky_webid/c/041.html

printfに引き続き、お次はscanfです。

まぁprintf程そんなに覚えることはなさそうです。

問題1

10件分の郵便番号を入力させ、最後にそれを画面に表示するプログラムを作って下さい。郵便番号は、 ○○○-○○○○ という形式で入力されるものとします。

うむを言わさずプログラミングです。

#define MAX 10

int main () {
    int zip3[MAX];
    int zip4[MAX];
    int i;
    
    for(i=0;i<MAX;++i){
        scanf("%3d%*c%4d",&zip3[i],&zip4[i]);
    }
    
    printf("郵便番号一覧\n");
    for(i=0;i<MAX;++i){
        printf("%03d-%04d\n",zip3[i],zip4[i]);
    }
    
    return 0;
}

できました。最後のprintfでは%03dのように0指定しないと3桁の数値にならない場合があるので注意。

答え合わせ

あーーなるほど。すっかり失念してました。構造体。

こういう時ほど構造体なんですね。確かにデータのつながり明確になるので今度からこういう場合は積極的に構造体を使っていこうと思います。

ちなみに問題自体は正解でした。

問題2

スキャン集合を使って、数字だけを文字列として入力するようなscanf関数を作って下さい。

スキャン集合ですね。OKまかせてください。

int num_scanf (int *num) {
    return scanf("%[0123456789]",num);
}

int main () {
    int num;
    
    num_scanf(&num);
    printf("%d",num);
    
    return 0;
}

はい!このプログラムは死ぬほどバグっています。数字だけというところに惑わされて何を思ったかint型をscanfに渡してしまいました。

ということで修正版はこちら

int num_scanf (char *str) {
    return scanf("%[0123456789]",str);
}

int main () {
    char str[81];
    
    num_scanf(str);
    printf("%s",str);
    
    return 0;
}
$ main
1234
1234

$ main
123e
123

修正できました。

と、いってもintをcharに変えただけですが。

答え合わせ

あってましたよ。

問題3

次のような形式で計算式を入力させ、その答えを画面に表示するプログラムを作って下さい。

整数 演算子 整数

「整数」と「演算子」の間には、それぞれ空白があります。「演算子」には+-*/%の5つがあります。

かなり複雑そうな問題が出てきました。やってみます。

struct enzan {
    int num1;
    int num2;
    char operant[1];
    int result;
};

int main () {
    struct enzan data;
    
    scanf("%d %1[+*-/%%] %d",&data.num1,data.operant,&data.num2);
    
    switch(data.operant[0]) {
        case '+':
            data.result = data.num1 + data.num2;
            break;
        case '-':
            data.result = data.num1 - data.num2;
            break;
        case '*':
            data.result = data.num1 * data.num2;
            break;
        case '/':
            if ( data.num2 == 0 ) {
                data.result = 0;
            }
            else {
                data.result = data.num1 / data.num2;
            }
            break;
        case '%':
            if ( data.num2 == 0 ) {
                data.result = 0;
            }
            else {
                data.result = data.num1 % data.num2;
            }
            break;
        default:
            printf("入力エラーです");
            return 1;
    }
    
    printf("%d %s %d = %d",data.num1,data.operant,data.num2,data.result);
    
    return 0;
}

できました。が、今回はかなり自身がないですorz

多分色々ダメだと思います。変な演算子の入力があるとアドレスが数値とみなされて変な演算結果になってしまいます・・・。

答え合わせ

あれれ?ほぼあってました。

解答例でも入力値エラーは考慮してなかったので今回はまだそこまでやる感じではないのでしょうか。

いやぁでも大分色々わかってきてちょっと楽しくなってきたのでこの調子でガンガンやっていきます。