★基本制御文(While10)★
見やすく、使いやすくということが重要と書きましたが、いくら見やすく、使いやすく作ったつもりでも、ユーザがいつも正しく使ってくれるとは限りません。
例えば、前回やった九九のプログラムですが、次のように使う人もいるかもしれません。
<sample program 037-01>
#include <stdio.h>
int main( void )
{
int counter;
int dan;
counter = 2;
printf( "2〜9までの整数を入力してください:" );
scanf( "%d", &dan );
while( counter <= 9 ) {
printf( "%d * %d = %2d\n", dan, counter, dan * counter );
counter++;
}
return 0;
}
|
<実行結果 VC++ Express Edition>
2〜9までの整数を入力してください:10
10 * 2 = 20
10 * 3 = 30
10 * 4 = 40
10 * 5 = 50
10 * 6 = 60
10 * 7 = 70
10 * 8 = 80
10 * 9 = 90
続行するには何かキーを押してください・・・
わざわざ「2〜9までの整数を入力してください:」と表示しているのですが、10を入力しています。
結果は正しく出ていますが、作った人が意図した使い方(九九の2〜9の段のどれかを表示する)とは違った使われ方をしています。
もしかすると、たまたま手が当たっただけかもしれません。
このような場合、ユーザを責めるのはお門違いです。
ユーザがどのような使い方をするか分からないため、ある程度こちらで対応をしておく必要があります。
まずは簡単なものから始めてみます。
数値を入力し、正数(1以上の数)でなければ再度入力させるというプログラムです。
<sample program 037-02>
#include <stdio.h>
int main( void )
{
int input;
printf( "正の数を入力してください:" );
scanf( "%d", &input );
if( input <= 0 ) {
printf( "正の数を入力してください:" );
scanf( "%d", &input );
}
printf( "入力された値は正の数です。\n" );
return 0;
}
|
<実行結果 VC++ Express Edition>
正の数を入力してください:0
正の数を入力してください:1
入力された値は正の数です。
続行するには何かキーを押してください・・・
上の実行結果を見てください。
最初に入力した「0」は正数ではありませんので、再度メッセージを表示しています。
次に入力した「1」は正数ですから「入力された値は正の数です。」と表示されています。
しかし、このような場合はどうでしょう。
<実行結果 VC++ Express Edition>
正の数を入力してください:0
正の数を入力してください:0
入力された値は正の数です。
続行するには何かキーを押してください・・・
2度目も「0」を入力した場合も「入力された値は正の数です。」と表示されています。
正数かどうかのチェックをif文で行っていますので、2度とも間違えると不正なデータのままプログラムを終了してしまいます。
実際には、正しいデータが入力されるまで「繰り返し」チェックを行う必要があります。
<sample program 037-03>
#include <stdio.h>
int main( void )
{
int input;
printf( "正の数を入力してください:" );
scanf( "%d", &input );
while( input <= 0 ) {
printf( "正の数を入力してください:" );
scanf( "%d", &input );
}
printf( "入力された値は正の数です。\n" );
return 0;
}
|
<実行結果 VC++ Express Edition>
正の数を入力してください:0
正の数を入力してください:-1
正の数を入力してください:5
入力された値は正の数です。
続行するには何かキーを押してください・・・
if文ではなく、while文を使うことで「繰り返し」チェックが出来るようになりました。
これで、正しいデータが入力されるまでは、while文を抜けなくなります。
では、九九のプログラムにもこの仕組みを取り入れてみましょう。
「2〜9までの整数」が入力されない限りは、チェックを繰り返します。
まずは、考えてみてください。
ヒントは、「while文の条件はif文の条件と同じように書ける」です。
解答例です。
<sample program 037-04>
#include <stdio.h>
int main( void )
{
int counter;
int dan;
counter = 2;
printf( "2〜9までの整数を入力してください:" );
scanf( "%d", &dan );
while( dan < 2 || dan > 9 ) {
printf( "2〜9までの整数を入力してください:" );
scanf( "%d", &dan );
}
while( counter <= 9 ) {
printf( "%d * %d = %2d\n", dan, counter, dan * counter );
counter++;
}
return 0;
}
|
<実行結果 VC++ Express Edition>
2〜9までの整数を入力してください:1
2〜9までの整数を入力してください:10
2〜9までの整数を入力してください:2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
続行するには何かキーを押してください・・・
「1」や「10」を入力すると、再度メッセージが出ています。
「2」を入力すると、きちんと九九の2の段が表示されました。
注目する箇所は、while文の
while( dan < 2 || dan > 9 ) {
というところです。
whileの条件として2つの条件文があります。
1つは、「 dan < 2 」← 変数 dan が 2
未満
1つは、「 dan > 9 」← 変数 dan が 9
より大きい
この2つの条件文が「||(オア演算子)」で連結されています。
「||」は「または」という意味ですから、
(変数 dan が 2未満) または (変数 dan
が 9より大きい)時に「繰り返す」という意味になります。
言い換えると、変数 dan が 2以上、9以下であれば「繰り返しを抜ける」ということです。
ヒントで「while文の条件はif文の条件と同じように書ける」と書きましたが、「条件の連結」もif文と同じように書けるのです。
これで、ユーザが間違った数値を入力する可能性が低くなりました。
※無くなった訳ではありません。
試しにアルファベット等を入力してみてください。
scanfを使っている限りこの問題を防ぐのは難しいのですが、対応策はずっと後に書きます。