見やすく、使いやすくということが重要と書きましたが、いくら見やすく、使いやすく作ったつもりでも、ユーザがいつも正しく使ってくれるとは限りません。
例えば、前回やった九九のプログラムですが、次のように使う人もいるかもしれません。
<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; } |
<実行結果>
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; } |
<実行結果>
正の数を入力してください:0 正の数を入力してください:1 入力された値は正の数です。 続行するには何かキーを押してください・・・
上の実行結果を見てください。
最初に入力した「0」は正数ではありませんので、再度メッセージを表示しています。
次に入力した「1」は正数ですから「入力された値は正の数です。」と表示されています。
しかし、このような場合はどうでしょう。
<実行結果>
正の数を入力してください: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; } |
<実行結果>
正の数を入力してください: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; } |
<実行結果>
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を使っている限りこの問題を防ぐのは難しいのですが、対応策はずっと後に書きます。