こんばんは、いつもお世話になっております。
よろしくおねがいします。
キーボードから入力された0から5までの整数値を受け取り処理を行いたいです。
はじめは、scanf関数で受け取っていましたが、これでは誤って文字入力がなされたときに無限ループになってしまいました。
そこで、getsやgetcharなどの関数を使って例外処理を行おうと思ったのですが、なかなかうまくいきません。
とりあえず、0から9までの整数値と、一文字の文字が入力されるかもしれないと考えて、例外処理を作成したいです。
思いついたのは、gets関数で一文字読み込み、atoi関数で整数値に変換する方法でしたが、atoi関数に文字を入れると0が返るので、整数値の0と被ってしまいます。
他によい方法はないでしょうか。
どなたか詳しい方がおられましたら、ご教示お願いします。
数値入力の例外処理について。
Re: 数値入力の例外処理について。
[補足]:
8行:読み取り+正当性のチェック
9行:不正な入力チェック
11行:余計な入力を取り除く
[独り言]
(人はふたのある器である。傷口から中身をほんの一部、拝見できただけでも、槍で刺したのは無駄ではなかったようです)
8行:読み取り+正当性のチェック
9行:不正な入力チェック
11行:余計な入力を取り除く
[独り言]
(人はふたのある器である。傷口から中身をほんの一部、拝見できただけでも、槍で刺したのは無駄ではなかったようです)
Re: 数値入力の例外処理について。
>>かずまさん
返信ありがとうございます!
書いていただいたコードを実行してみたら、うまく処理することができました。すごくうれしいです。
ありがとうございます。
>>ただの屍のようださん
返信ありがとうございます!
補足説明うれしいです(><)
お二人の返信を参考に、自分なりにコードについて調べてみましたが、よくわからないところがあるので
さらに質問させていただきます。
勉強不足で申し訳ありません。
feof(stdin)は、stdinがファイルの終わりがあると0以外、終わりがないと0を返すようですが、
文字入力されたとき、どうして0が返るのでしょうか。
また、11行目の意味は、改行を取り除いている、でいいでしょうか。
よろしくおねがいします。
返信ありがとうございます!
書いていただいたコードを実行してみたら、うまく処理することができました。すごくうれしいです。
ありがとうございます。
>>ただの屍のようださん
返信ありがとうございます!
補足説明うれしいです(><)
お二人の返信を参考に、自分なりにコードについて調べてみましたが、よくわからないところがあるので
さらに質問させていただきます。
勉強不足で申し訳ありません。
feof(stdin)は、stdinがファイルの終わりがあると0以外、終わりがないと0を返すようですが、
文字入力されたとき、どうして0が返るのでしょうか。
また、11行目の意味は、改行を取り除いている、でいいでしょうか。
よろしくおねがいします。
Re: 数値入力の例外処理について。
文字入力されたとき、feof(stdin) は 0 を返しません。 と書き換えてみたら分かります。いちこ さんが書きました: feof(stdin)は、stdinがファイルの終わりがあると0以外、終わりがないと0を返すようですが、
文字入力されたとき、どうして0が返るのでしょうか。
もっとたくさんの入力があるプログラムを書いて、デバッグするとき、
何度も同じキーボードから入力をするのは大変ですから、
ファイルに入力データを書いておいて、標準入力(stdin) をそのファイルに
切り替えることがあります。ファイルには終わりがあります。
scanf("%d", &a) は 3通りの値を返します。
1: 数字からなる文字列を読み込んで、数値に変換できた。
0: 数字以外の文字があったので、数値に変換できなかった。
EOF: 空白以外の文字がなく入力の終わりに達して、数値に変換できなかった。
int n;
...
n = scanf("%d", &a);
if (n == 1 && a >= 0 && a <= 5) break;
if (n == EOF) { printf("EOF\n"); return 1; }
// ここに来たら n == 0
改行は取り除きません。改行の直前までの文字をすべて取り除きます。いちこ さんが書きました: また、11行目の意味は、改行を取り除いている、でいいでしょうか。
改行を取り除くのは次の scanf("%d", &a) の "%d" です。
"%d" は、空白を読み飛ばしたあと、あれば '+' か '-' の符号を、そして数字の列を読み込みます。
空白というのは、スペースやタブ以外に改行も含みます。
%d だけでなく、%s も %x も %f も空白を読み飛ばします。
空白を読み飛ばさないのは "%c" と %[" と "%n" ぐらいでしょう。
Re: 数値入力の例外処理について。
>>かずまさん
返信ありがとうございます。
返信が遅くなってしまい申し訳ありません。
丁寧に教えてくださってありがとうございます。
scanfは空白を読み飛ばした後数字を読み込む、というのは自分でも調べてみて理解することができました。
ですが、
scanf("%*[^\n]");
というのが、なんだかよくわかりません。
この処理がないと、文字を入力したとき無限ループになってしまいますが、それはなぜなのでしょうか。
また、標準入力から値を受け取ったscanfがEOFを返すときは、Ctrl+z が押されたとき、で正しいでしょうか。
至らなくて申し訳ありませんが、よろしければご教示ください。
返信ありがとうございます。
返信が遅くなってしまい申し訳ありません。
丁寧に教えてくださってありがとうございます。
scanfは空白を読み飛ばした後数字を読み込む、というのは自分でも調べてみて理解することができました。
ですが、
scanf("%*[^\n]");
というのが、なんだかよくわかりません。
この処理がないと、文字を入力したとき無限ループになってしまいますが、それはなぜなのでしょうか。
また、標準入力から値を受け取ったscanfがEOFを返すときは、Ctrl+z が押されたとき、で正しいでしょうか。
至らなくて申し訳ありませんが、よろしければご教示ください。
Re: 数値入力の例外処理について。
> scanf("%*[^\n]");
書式については scanf で検索するとすぐ見つかります.
↓リンクはwikipediaですが
http://ja.wikipedia.org/wiki/Scanf
役割については,既に説明されているように,
改行文字直前までを入力ストリームのバッファ(? 正式名称わからないけど,入力された内容がたまっている場所)から
読み込む(が,特に変数に格納したりしない = 取り除く)ことです.
scanf()は,予期せぬ入力:今回の例では数値を入力してほしいのにアルファベットを入力されたようなとき があったら
その入力を入力ストリームバッファから取り除かずに残したままにするので,これを放置しておくと
次回のscanf()で再びこのアルファベットに出くわし→放置→また出くわし…
ということになります.
書式については scanf で検索するとすぐ見つかります.
↓リンクはwikipediaですが
http://ja.wikipedia.org/wiki/Scanf
役割については,既に説明されているように,
改行文字直前までを入力ストリームのバッファ(? 正式名称わからないけど,入力された内容がたまっている場所)から
読み込む(が,特に変数に格納したりしない = 取り除く)ことです.
scanf()は,予期せぬ入力:今回の例では数値を入力してほしいのにアルファベットを入力されたようなとき があったら
その入力を入力ストリームバッファから取り除かずに残したままにするので,これを放置しておくと
次回のscanf()で再びこのアルファベットに出くわし→放置→また出くわし…
ということになります.
Re: 数値入力の例外処理について。
>>usaoさん
返信ありがとうございます。
なるほどです。丁寧に説明してくださってありがとうございます。
もっと勉強します。
みなさんありがとうございました。
返信ありがとうございます。
なるほどです。丁寧に説明してくださってありがとうございます。
だから無限ループになってしまうんですね。usao さんが書きました: 次回のscanf()で再びこのアルファベットに出くわし→放置→また出くわし…
もっと勉強します。
みなさんありがとうございました。