例えば、2項目か3項目から成る数値や文字データを1行で読みたい場合、入力 データがプログラムと整合していなければなりませんが、入力するのが人間だ としたら、ちょっとしたキーの打ち間違いや項目を飛ばすといったことはしょっ ちゅうあります。極端な話、そのたびにプログラムが暴走するようではたまり ません。
このプログラムは、scanfにおけるそのような問題点を確認するためのも のです。scanfにより、キーボードから入力された「月、日、メモ、体重、体 脂肪率」を読み込み、それを単に打ち出すだけのプログラムです。このソース のコメントに添付したデータ以外も、いろいろな書式で試してみてください。 プログラムが、何か文字をプリントし続けて止まらない(暴走する)ときは、 慌てずC-c(コントロールキーを押しながら、cキーを押す)で止めましょう。
上の例(体脂肪プログラム?)を、この方法で書き直すと このようになります。 scanfのときと同じテストデータで試してみてください。不正入力のときの動 作はどうなるでしょうか。
その骨組みは、次の通りです。
char buf[BUFSIZE]; /* fgetsで読んだ文字を一旦格納する場所 */
int month, day; double weight, fat; char note[128];
.....
fgets(buf, sizeof buf, stdin); /* 標準入力からbufへ読み込む */
sscanf(buf, "%2d/%2d %s %lf %lf",
&month, &day, note, &weight, &fat);
/* bufの文字を書式に従って変換 */
sscanfは、変換に成功した数を返す(この場合は5)ので、これをチェックする
ことができます。このプログラムでは、入力ミスがあれば何もエコーバックせ
ず、ただ次のデータ入力を待ちますが、既定値を使う、ミスを指摘する、など
これ以外の処理も可能なことは容易に想像できると思います。そこから先は、
入出力インターフェースをどのように設計するかという問題になる訳です。
このような「(キーボードからの)入力文字を一時バッファに読み込み、それを 数値その他に変換する」という二段階処理は、実はこれまでにも使ってきまし た。
これに対して、上で見たsscanfは、(メモリー内の)文字列を入力対象としてい る点で、大きく異なります。つまり、一旦バッファに読み込んだ長い文字列 (たぶん、数値、文字以外に、空白やカンマや改行などを含むかもしれない) を、指定書式に従って変換するためのものです。 それで、文字列を丸のみするための関数 fgets と組み合わせて使う訳です。
そうした訳で、データの入力には、fgets+sscanfを組み合わせるのが安全です。 (sscanfは書式変換のためですから、データ型によってはatoiなど他の手段を 使ってもよい)。
[自習] 自分の計算機環境で、fgets, atoi, fscanf, fprintf について調べなさい。
この書式は、簡単に画像を作れる点で便利であるが、少し複雑なイメージを作 るには不便である。このためには、プログラムで確保したメモリにイメージデー タを描き、それをバイナリ出力する必要がある。このプロ グラムはそのような例である。これによって作られるファイルは、xvなど のビューアで見ることができる。
© Copyright 2001 Hitoshi Maekawa. All right reserved.
Up to Programming Lang. home.
Up to lectures-etc.