No.15550![]() |
scanf()とfgets()が混在してあるプログラムについて 投稿者---kamina(2004/07/15 17:07:30) |
||
はじめまして、kaminaと申します。よろしくお願いします。 ここの標準入出力関数(1)のscanf()の部分について読んでいて、プログラムを作ったのですが、うまくいかないときがあります。 たとえば・・・ void main() { int a; char b[10]; printf("数字いれて"); scanf("%d", a); printf("文字入れて"); fgets(b, sizeof b, stdin); sscanf(b,"%s",&b); } というような形でつくり、コンパイル後、実行しても文字が入りません。 scanf()後に\n が必ず入力されるということはわかったのですが、 この場合fgets()を使った場合は\nを飛ばして入力できると思いましたが、 文字が入力できませんでした。 fgets()について自分の認識不足もあると思いますが、解決できずにいます。scanf()のあとに、fgets()を入れてはいけないのでしょうか? ※本には、あまりscanf()を多用するな的なことが書いてありましたので・・ また、解決法があるとすれば、どのようにすればいいのでしょうか? 申し訳ありませんが、どなたかご教授していただければ幸いです。 |
No.15552![]() |
Re:scanf()とfgets()が混在してあるプログラムについて 投稿者---あかま(2004/07/15 18:10:19) |
||
http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-4 ↑ここは読みました? >scanf()後に\n が必ず入力されるということはわかったのですが、 後ではなく、scanfの入力時ですね。そのときの'\n'が残ります。 >この場合fgets()を使った場合は\nを飛ばして入力できると思いましたが、 >文字が入力できませんでした。 fgetsは'\n'を読み込みます。読み込んだら読み込みを打ち切ります。 ですのでscanfの後だと入力できません。 >scanf()のあとに、fgets()を入れてはいけないのでしょうか? 入れる前に読み捨てをすればいいでしょう。 fgetsを2回にするとか。 fgetsしてからsscanfで分けるとか。 >※本には、あまりscanf()を多用するな的なことが書いてありましたので・・ セキュリティホール云々でそう書かれることが多いですが、そんなことないですよ。 便利なものは使ったほうがいいです。 ただ、scanfは間違った入力の時に問題があって、 #include <stdio.h> int main(){ int i=1; while(i){//0の入力で終了 scanf("%d",&i); printf("%d",i); } } こんなプログラムを書いたときに、数字以外の入力をすると バッファに文字が残り続けるために無限ループします。 #include <stdio.h> int main(){ int i=1; char str[256]; while(i){ fgets(str,256,stdin); sscanf(str,"%d",&i); printf("%d",i); } } なので、fgetsとsscanfを組み合わせるとよりよいかと思います。 |
No.15553![]() |
Re:scanf()とfgets()が混在してあるプログラムについて 投稿者---NykR(2004/07/15 18:17:31) |
||
>というような形でつくり、コンパイル後、実行しても文字が入りません。 >scanf()後に\n が必ず入力されるということはわかったのですが、 >この場合fgets()を使った場合は\nを飛ばして入力できると思いましたが、 scanfの%dは、次の非空白類文字から、整数に変換できない文字の直前までを読み込みます。 ですから、「\nが入力される」と言うよりは、入力された\nが取り残されるわけですね。 fgetsは、直前の入力終わりの次の文字から改行文字までを読み込みます。 ですから、いきなり改行文字があれば、改行文字だけを読むことになります。 「\nを *飛ばして* 入力」なんて器用なことはできません。 # scanfの%sならできますが。 >fgets()について自分の認識不足もあると思いますが、解決できずにいます。scanf()のあとに、fgets()を入れてはいけないのでしょうか? いけないことはないですが、それで得をするようなことも滅多にありません。scanfを使うなら、scanfだけを使い続けた方がいいです。 # 改行をとばせるから >※本には、あまりscanf()を多用するな的なことが書いてありましたので・・ scanfは、改行文字とそのほかの空白類文字を区別できないので、1行入力を受け付けるのには向きません。fgetsを使う方がいいです。 逆に、行を認識しなくていいような入力で、字句解析を行うようなものを書くときは、scanfを使わないとやってられません。 行を認識しなくていいような入力で、あまり大袈裟なことをやらない場合はgetcharを使うといいでしょう。 # 行を認識しなければならないような入力で、字句解析を行うようなものを書くとき、(strtokじゃ間に合わない場合)はどうするんでしょう。fgetsとsscanfの%n? >また、解決法があるとすれば、どのようにすればいいのでしょうか? ・scanf("%*[\n]");をfgetsの前に入れる。 ・fgetsの代わりにscanfの%sを使う。 ・最初の入力は scanfで入力受付と解析を一度にやるようになっているが、これを、fgetsで入力を受け付けてからsscanfで解析するように変更する。 普通は3つ目の方法を使うと思います。 |