大学のプログラミングの課題が最近複雑になってきたので、ちょっとまとめて見たいと思います。
今回は、入力処理について見ていこうと思います。最初だけよく使うscanfの使いかたを取り上げます。
scanfの基本的な使いかたは以下のようなものですね。
今回は、入力処理について見ていこうと思います。最初だけよく使うscanfの使いかたを取り上げます。
scanfの基本的な使いかたは以下のようなものですね。
int a;このコードは数値を読み取るものです。これは、まだ安全なコードですが、非常に不安定な動作になるときがあるので、それを重視して説明していきます。
scanf("%d", &a);
その非常に危険なコードがこれです。
このコードの危険なところは、「数値以外を入力すると無限ループになる」と言うところです。
なぜなら、標準入力に数値以外のデータが残ってしまっているからです。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"); // 文字列を読み込むが、どこにも格納しない。
これをすることによって、標準入力にあるデータを消去することができます。
これを使って直したコードが以下の通り
%*[^\n]は、改行がくるまで読み込むということです。次の%*cは、標準入力に改行が残っているのでそれの読み込みです。
取り合えずこれで、無限ループは止まっているはずです。ただし、十分にテストしていないので、まだ異常があるかもしれません。
数値の入力はこれで終わりです。次回は、文字列をやってみようと思います。(いつになるかは未定)
#include <stdio.h>あんまり面白くないサンプルです。このプログラムは、標準入力から数値を読み取り、入力した数値を出力し、-1で終了するプログラムです。
int main() {
int a;
while (1) {
scanf("%d", &a);
if (a == -1) {
break;
}
printf("%d\n", a);
}
return 0;
}
このコードの危険なところは、「数値以外を入力すると無限ループになる」と言うところです。
なぜなら、標準入力に数値以外のデータが残ってしまっているからです。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>ifで正しく入力されなかったときに、scanfを使って無駄読み込みしています。
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;
}
%*[^\n]は、改行がくるまで読み込むということです。次の%*cは、標準入力に改行が残っているのでそれの読み込みです。
取り合えずこれで、無限ループは止まっているはずです。ただし、十分にテストしていないので、まだ異常があるかもしれません。
数値の入力はこれで終わりです。次回は、文字列をやってみようと思います。(いつになるかは未定)
コメントする