Previous: 入力の読み込みと制御構造
Up: 入力の読み込みと制御構造
Next: 実行プログラムの名前
Previous Page: 入力の読み込みと制御構造
Next Page: 実行プログラムの名前
入力の読み込みと一口に言っても、状況により様々な事が要求される。 単に、キーボードから数値を読み込む場合、あるいは、ファイルから 読み込む場合、さらには、文字なども含めて読み込む場合など、 入力方法の種類は多種多様である。幸いなことに、UNIX では、標準 入力という概念があり、キーボード入力とファイルからの入力とは、 プログラムから見ると同じに取り扱える仕組みがある。従って、今回 我々が学習するのは、標準入力の読み込みに的を絞り、ファイルから 直接入力することは後に学ぶ。更に、入力されてくるものは、一般には 文字であるが、ここでは、整数のみに限定する。(これらの一般への 拡張は難しくない。)
整数変数への標準入力からの読み込みは、scanf という標準関数を用いる。 その書式は、以下のとおりである。
scanf("%d",&整数変数名);
ここで、整数変数名の前についている & は、実は重要な意味を持っている
のだが、ここでは重要な意味を持つおまじないと思っておけばよい。
ダブルクォーテーションで囲まれた %d は、printf の時と同じ意味で、
整数変数に対応した整数という意味である。
例1
int a;
scanf("%d",&a);
この例では、整数変数 a に、標準入力から整数を読み込む。しかし、
ディスプレイには、入力をうながすような目印は何も出ないので、これでは
いささか不親切であるので、次の例のように通常は printf と組にして
使うほうが良い。
例2
int a;
printf("整数を入力してください。 a = ");
scanf("%d",&a);
これで、画面上には、
整数を入力してください。 a =と出力され、ユーザーがキーボードから整数を入力するまで、プログラムは 待つことになる。
しかし、これでも問題がある。何故ならば、もし、ユーザーが間違って文字を いれたとしよう。この場合、変数 a には0が入力される。何故ならば、scanf は、間違った入力であるとして、偽と判断し、0を代入するからだ。 では、0だったら常に入力が間違っていたと考えてはいけない。ユーザーが 本当に0のつもりで入力したかも知れないからである。従って、間違って、 入力したかどうかを知る手段が必要であるが、実は、scanf にはその機能も 備わっている。どうなっているかと言うと、scanf は、入力された個数を 返すようになっているのである。つまり、scanf は、キーボードからの 入力を読み取り、その読み込んだ個数を表わすと思えばよい(この例の 場合、1個しか読み込んでないので、結果は0又は1である)。個数であるので、 返ってくるのは整数である。そこで、例2を改良すると以下のようになる。
例3
int a, kosuu;
printf("整数を入力してください。 a = ");
kosuu = scanf("%d",&a);
if ( kosuu==0 ){
printf("入力が違います。\n");
}else{
printf("入力した数値は、a = %d\n",a);
}
この例では、まず、キーボードから読み取った数値を変数 a に代入し、
scanf はその個数を返すので、それを変数 kosuu に代入している。
従って、もし、入力されたものが、整数ではなく、他の物であったら、
kosuu には0が入っているはずなので、それを次の if 文で判断して、
0ならば入力が間違っているというメッセージを出し、正しく入力
されていたら、入力した数値を表示するようにしている。
例3では、分かりやすく入力の個数を変数 kosuu に代入していたが、 これはもっと簡単に書くことが出来る。
例4
int a;
printf("整数を入力してください。 a = ");
if ( scanf("%d",&a)==0 ){
printf("入力が違います。\n");
}else{
printf("入力した数値は、a = %d\n",a);
}
scanf の結果を判断しているのは1箇所なので、整数変数を使わずに、
そこに直接 scanf を書いている。c 言語では、こういう便利な事が
出来ることが一つの特徴である。ところが、実は、この例は更に
簡単に書ける。
例5
int a;
printf("整数を入力してください。 a = ");
if ( scanf("%d",&a) ){
printf("入力した数値は、a = %d\n",a);
}else{
printf("入力が違います。\n");
}
例4との違いを良く比べてみよう。例4では、scanf の結果と0とを
if 文の条件で比較していたが、今度はそれがない。これは、scanf が
間違った入力の際には、偽の0を返していることを使っている。
従って、真である場合には正しい入力なので、printf の位置が
逆転している。
例4、5では、入力が間違っていた場合、再入力するためには、もう 一度プログラムを実行し直す必要があった。しかし、多くの入力を 要するプログラムでは、一度の間違いのために何度も入力をやり直させる のは、不親切というべきであろう。従って、入力が間違っていたら、 何度でも正しい入力が得られるまで繰り返すように変更してみよう。
例6
int a;
printf("整数を入力してください。 a = ");
for (; scanf("%d",&a)==0 ;){
printf("入力が間違っています。\n a = ");
}
printf(" a = %d \n",a);
ここでは、繰り返しのために for 文を用いている。まず、初期化は
何も指定されていないので、継続条件が判定される。継続条件は、
scanf("%d",&a)==0 なので、まず、scanf が実行され、
その結果が0と比較される。もし、入力が間違っていた場合は0なので
継続条件が真となり、「入力が間違っています。」が表示された後、
改行されて、「a = 」が表示されて、再び、継続条件の判定に移る。
重要なことは、最初に継続条件が判定されるので、もし、正しい
入力だったら継続条件は偽となり、その場合は、for 文の中の文は
実行されない点である。