
C言語の勉強をしております。
初歩的な質問なのかもしれないですが、
char buf[80];
char data[32];
fgets(buf,sizeof(buf),stdin);
sscanf(data, "%s", buf);
と、
fgets(data, sizeof(buf), stdin);
は何が違うのでしょう?
他の質問内容やネットで探してみたんですが、基本的には組み合わせて使用されているみたいなんですが、必要性がわかりません・・・。
例えば、fgetsで構造体のメンバ(文字配列)へキーボードからデータを入力したい場合は、どちらで行うのが良いのでしょう?
また、入力データが未入力かどうか判断させるには、
fgets(buf,sizeof(buf),stdin);
if(buffer[0] == '\n'){
/* ループを抜ける */
break;
}
で良いですよね?
※関連している質問
http://oshiete1.goo.ne.jp/qa4438371.html
あと、同じ処理内で、getsやscanfを混同して使用すると、どこかの入力時に改行がバッファに残ってしまい、入力処理が飛ばされてしまいますか?
以上、よろしくお願いいたします。
No.4ベストアンサー
- 回答日時:
scanf 系の %s 変換は, 「先頭の空白文字を無視する」&「それ以外の最初の空白文字までを取り出す」という仕様です. だから, 直接 fgets するのとは意味が異なります. 例えば
[SP][SP][SP]abcd[SP]efg[CR]
という行 ([SP] は空白を, [CR] は改行をあらわす)
があると, fgets+sscanf では「abcd」が得られるはずです (fgets では行頭の空白文字も含めて入力されるので違う結果になります).
で, scanf 系で %s 変換すると「得られた文字列の後ろにある空白文字」はそのまま残ります (上の行を scanf なり fscanf なりで取り込むと, d のあとの空白文字以降がストリームに残ったままになります). なので, scanf してから fgets するとこの空白文字が邪魔をすることがあります. つまり
abcd[CR]
という行を scanf で取り込むと, 行末の改行文字がストリームに残るので直後の fgets ではこの改行文字を取り込むことになります. これが嫌な時は, scanf の書式文字列を工夫するのが本手でしょう.
でも, gets はともかく scanf 系ならバッファサイズも指定できるんじゃなかったっけ....
例を取り入れてくださり、初心者の私にもとても分かりやすい説明です。
本当にありがとうございます。
回答者様にはいつも助けられてばかりで感謝感謝です。
No.5
- 回答日時:
●回答1
> char buf[80];
> char data[32];
>
> fgets(buf,sizeof(buf),stdin);
> sscanf(data, "%s", buf);
>
> と、
>
> fgets(data, sizeof(buf), stdin);
の違いを答えたいと思いますが、
その前に、
> fgets(buf,sizeof(buf),stdin);
> sscanf(data, "%s", buf);
これは、
fgets(buf,sizeof(buf),stdin);
sscanf(buf, "%s", data);
の間違いじゃないかな。
と言う事で、
fgets()関数にの内容は、リファレンスを参照すればわかると思いますが、
一行のデータを読み込む処理ですね。入力データに改行が含まれていれば、
bufの末尾に改行コードが付きます。
# リファレンス読んで見ましたか?
sscanf()を使って、改行コードを除去してる所ですね。
●回答2
fgets()+sscanf()を組み合わせる事のメリットですが、
行末の改行を除去するだけの処理でしたら、他にも実装方法はありそうですが、
sscanfを使う事によって、%dとか%xとかを使った入力にも応用が利きます。
●回答3
> あと、同じ処理内で、getsやscanfを混同して使用すると、どこかの入力時に改行がバッファに残ってしまい、入力処理が飛ばされてしまいますか?
気をつけてプログラミングすれば改行バッファに残る事はありませんが、
場合によっては、読みにくいコードになってしまうかもしれません。
注意です。
改行がバッファに残ってしまい、入力処理が飛ばされるような状況におちいった場合は、
変数のダンプ、トレースなどして、みると原因を見つけるのに役立つと思います。
●おまけ
gets()の代わりにfgets()を使うのは、人それぞれだと思います。
たぶん好みの違いだと思います。
が、
fgets()ではなく、gets()を使った場合、バッファサイズを指定できないので、
バッファあふれになる危険性があります。
C言語でバッファオーバーした場合、どのような動作になるかは予想が付きませんので、
回避策の1つとして、fgets()が有効です。
メリットなどを含め、とても丁寧なご回答ありがとうございます。
リファレンスというか、参考書に書いてある内容は読んだんですが、外国の本が訳してあるので、日本語が分かりづらく書いてあり、苦戦しております・・・。
ネットで見るようにいたします。
何日か考えた結果、キーボードからの入力には基本的に
「fgets」+「sscanf」の組み合わせでプログラミングしていきたいと思います。
本当にありがとうございました。
No.1
- 回答日時:
sscanf, gets はバッファサイズが指定できないので
大サイズの入力があるとシステムを破壊してしまいます。
恐ろしいですね。
ウィルス騒動の原因もここらへんにあったり。
>あと、同じ処理内で、getsやscanfを混同して使用すると、どこかの入力時に改行がバッファに残ってしまい、入力処理が飛ばさ
エラーで終わって クリア処理してないのでは。
void
clearerr(FILE *stream);The function clearerr() clears the end-of-file and error indicators for
the stream pointed to by stream.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのコマンドボタンの文字列の...
-
改行について
-
【VBA】エクセルで最後の不要な...
-
VBAでCSVをExcelに取り込む時に...
-
エスケープ文字の復帰(¥r)と...
-
C言語の標準入力で改行しない方法
-
LaTeX: captionの中で改行した...
-
ソースコードの1行が長いとき...
-
C++で空Enterの入力を判...
-
CSVファイルの改行コード判別
-
ラベル(スタティックテキスト)...
-
最終行の改行について
-
C# DataGridViewのセルを改行禁...
-
jsp 改行コードで改行させて表...
-
ExcelVBAでメールを作成してメ...
-
エディットボックスで改行
-
1行ごとに取得して、その改行...
-
改行コードが半角スペースにな...
-
「続行するには何かキーを押し...
-
エクセルVBA 文字列領域が不足...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのコマンドボタンの文字列の...
-
ソースコードの1行が長いとき...
-
エスケープ文字の復帰(¥r)と...
-
jsp 改行コードで改行させて表...
-
改行について
-
VBAでCSVをExcelに取り込む時に...
-
【VBA】エクセルで最後の不要な...
-
ファイルから読み取った改行文...
-
ラベル(スタティックテキスト)...
-
Excel VBAからBeckyを起動して...
-
C++で空Enterの入力を判...
-
JAVA Spring 改行コードを含む...
-
秀丸の正規表現で複数行にわた...
-
変数の中の改行コードをBRタグ...
-
エクセルVBA 文字列領域が不足...
-
awkで改行を除いて文字列を抜き...
-
COBOLの改行
-
vb.netでのリッチテキストボッ...
-
グレープシティのSPREAD...
-
最終行の改行について
おすすめ情報