[C言語] 入力処理について (数値編)

| コメント(0) | トラックバック(0) |
大学のプログラミングの課題が最近複雑になってきたので、ちょっとまとめて見たいと思います。
今回は、入力処理について見ていこうと思います。最初だけよく使うscanfの使いかたを取り上げます。

scanfの基本的な使いかたは以下のようなものですね。
int a;

scanf("%d", &a);
このコードは数値を読み取るものです。これは、まだ安全なコードですが、非常に不安定な動作になるときがあるので、それを重視して説明していきます。
その非常に危険なコードがこれです。
#include <stdio.h>

int main() {
    int a;

    while (1) {
        scanf("%d", &a);
        if (a == -1) {
            break;
        }
        printf("%d\n", a);
    }

    return 0;
}
あんまり面白くないサンプルです。このプログラムは、標準入力から数値を読み取り、入力した数値を出力し、-1で終了するプログラムです。

このコードの危険なところは、「数値以外を入力すると無限ループになる」と言うところです。
なぜなら、標準入力に数値以外のデータが残ってしまっているからです。scanf("%d", &a)は、"%d"になっているので、10進数のみを読み込みますそれ以外は、なにもしません
なので、10進数以外(文字列など)が入力されたとき、aの値は変化しないので、ifの条件式が永遠に偽になり、無限ループになります。

これを防ぐには、scanfの戻り値と、標準入力の無駄読み込みをを使います。

scanfの戻り値は、格納した要素の個数です。今回のscanf("%d", &a)では、数値が正常に入力されていれば、1、それが入力されていれば、0が返ります。(因みに、WindowsでCtrl+Z、UNIX系でCtrl+Dを使ってEOF入力すると、EOFが返ります。)
これを使って、正常に入力されたかどうかを確認することができます。
異常入力で、終了させる場合は、ここの判定でプログラムを終了されればいいですが、続けて実行させたい場合は、次にあげる処理が必要です。

標準入力に残っているデータを、変数・配列に格納せずに読み込みます。その方法は、%と変換指定子の間に、*(アスタリスク)を書き加えます。
例: scanf("%*s");      // 文字列を読み込むが、どこにも格納しない。
これをすることによって、標準入力にあるデータを消去することができます。

これを使って直したコードが以下の通り
#include <stdio.h>

int main() {
    int a;

    while (1) {
        if (scanf("%d", &a) != 1) {
           
scanf("%*[^\n]%*c");
            continue;
        }

        if (a == -1) {
            break;
        }
        printf("%d\n", a);
    }

    return 0;
}
ifで正しく入力されなかったときに、scanfを使って無駄読み込みしています。
%*[^\n]は、改行がくるまで読み込むということです。次の%*cは、標準入力に改行が残っているのでそれの読み込みです。

取り合えずこれで、無限ループは止まっているはずです。ただし、十分にテストしていないので、まだ異常があるかもしれません。

数値の入力はこれで終わりです。次回は、文字列をやってみようと思います。(いつになるかは未定)

トラックバック(0)

トラックバックURL: https://www.letstryit.net/mt/mt-tb.cgi/122

コメントする

アーカイブ

カウンタ

Total
Today
Yesterday

IPv6 Ready

Powered by Movable Type 7.0

このブログ記事について

このページは、enjoypcが2009年10月14日 15:26に書いたブログ記事です。

ひとつ前のブログ記事は「SH-06Aのレビュー (4) カメラ」です。

次のブログ記事は「ネットワークスペシャリスト試験を受けてきました」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ