- 締切済み
fgetsについて
いつも大変お世話になっております。 またしても基本的なことで恐縮ですが、教えてください。 『fgets()』を使って、標準入力ファイル(stdin)からの情報を読み込む場合、指定されたサイズ以上を入力すると、サイズを超えた部分が切捨てられて最後に'\n'が自動的に付加されると学習しました。 しかし、切り捨てられた部分はまだstdinに残るため、次回の利用でおかしな結果を招くようです。 そこで、stdinのバッファをクリアたほうが良いと思ったのですが、方法が分かりません。 どのようにすればよいでしょうか? 【例】 #include<stdio.h> #include<string.h> char name[5]; printf("文字列を入力して下さい。>>"); fgets(name,sizeof(name)-1,stdin); printf("読み込み文字列:%s\n",name); このとき、キーボードから4文字入力するとstdinのバッファに'\n'が残ってしまい、5文字以上だと4文字目以降の文字と'\n'が残ってしまうようです。 また、最後に'\0'が付与されるなら、サイズ以上が切捨てられた際もname[4]に'\0'を代入しなくてもいいということでよいのでしょうか? 乱文になってしまい、申し訳ありません。 どうぞ教えてください。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- Tacosan
- ベストアンサー率23% (3656/15482)
よく誤解されるけど '\0' と NULL は違います. 規格上整定数0 は NULL として使えて, かつ '\0' は整定数0 なので NULL のところで '\0' を使っても正しく動作するんだけど, 概念的には別物 ('\0' は「文字コード0 の文字」, NULL は「ヌルポインタ = 何もささないことが保証されているポインタ定数」) です.
- yukimican
- ベストアンサー率70% (112/159)
No.1 補足より > 本当に'\0’が入ったかどうかは、どのように確認したらよいのでしょうか? 1文字ずつ数値で表示して、ASCIIコード表と照らし合わせてください。 '\0'の値は10進数だと0です。 http://e-words.jp/p/r-ascii.html No.4さんの書式についてはこの辺を参考にしてください。 http://www.mm2d.net/c/c-01.shtml この場合は、4文字だけバッファに取り込み、改行文字と超過分を読み捨てるようになっています。
- jacta
- ベストアンサー率26% (845/3158)
getsの代わりにfgetsを使えという場合が多いこともあって、単純に置き換えられると考えている人も多いようですが、fgetsをまともに扱うのも結構面倒なものです。 今回の場合、いっそのこと次のようにしてはどうでしょうか? char name[5]; scanf("%4s%*[^\n]%*c", name);
補足
jacta様 ご回答をありがとうございます! scanfですね! 教えていただいて恐縮なのですが、再度質問させてください。 書式設定の『"%4s%*[^\n]%*c" 』で、*と[^\n]は、一体どういう意味なのでしょうか? 調べてみたのですが、よく分からないのです…。
- koko_u_
- ベストアンサー率18% (459/2509)
しまった。fpurge って BSD にしかないや。
- koko_u_
- ベストアンサー率18% (459/2509)
int fpurge(FILE* stream);
- yukimican
- ベストアンサー率70% (112/159)
stdinのバッファをクリアするためには、 バッファが空になるまでひたすらデータ取得する必要がありますね。 詳しくはこのへんを見てください。 http://kitaj.at.infoseek.co.jp/fgets.html http://kitaj.at.infoseek.co.jp/c_prog2.html > また、最後に'\0'が付与されるなら、サイズ以上が切捨てられた際も > name[4]に'\0'を代入しなくてもいいということでよいのでしょうか? 実際にいくつかテストパターンを用意して、それぞれの場合で printfを使って取得した文字列を1文字ずつ(数値で)表示してみると 理解しやすいかと思います。
補足
yukimican様 丁寧なご回答をありがとうございます! リンクしていただいたサイトを拝見し、とても勉強になりました。 教えていただいた通り、'\0'が付加されるかを確認するため簡単なソースをいくつか作ってみました。 要素数を変えて、読み込んだ文字列を表示しただけなのですが、何回か試したところやはり指定した読込み文字数より1文字少なく読み込まれることが分かりました。 しかし、最後に'\0'と表示されないのですが、本当に'\0’が入ったかどうかは、どのように確認したらよいのでしょうか? たびたびの質問で申し訳ありません。
お礼
yukimican様 いつも丁寧にご回答いただき、ありがとうございます! 早速両サイトを拝見いたしましたところ、無事に'\0'が入っていることを確認できました。('\0'は=NULLで'0'なのですね) また、書式についても勉強になりました。 かねてからの疑問であった「*」は読み捨ての時に使う記号なのですね。これなら、文字数を制限できるので、とても便利です! 本当にどうもありがとうございました。