web-dev-qa-db-ja.com

fgetsとfscanfの違いは?

Cのfgetsとfscanfについて質問があります。これら2つの違いは正確には何ですか?例えば:

char str[10];
while(fgets(str,10,ptr))
{
counter++;
...

そして2番目の例:

char str[10];
while(fscanf(ptr,"%s",str))
{
counter++;
...

空のスペースで区切られた文字列を含むテキストファイルがある場合。例:AB1234 AC5423AS1433。最初の例では、whileループの「カウンター」は2番目の例と同じ出力を提供しません。 fgets関数の「10」を変更すると、カウンターは常に異なる結果を返します。これの理由は何ですか?誰かがfscanfが正確に何をするのか、各whileループの文字列の長さも説明できますか?

8
Chris

関数fgetsは、改行まで読み取ります(また、改行します)。 fscanf%s指定子は空白スペースまで読み取り、それを格納しません。

ちなみに、scanfでバッファのサイズを指定していないため、安全ではありません。試してください:

fscanf(ptr, "%9s", str)
7
cnicutar

fgetsは改行を読み取ります。 fscanfは空白までしか読み取りません。

3
Carl Norum

あなたの例では、fgetsは入力ストリームから最大9文字を読み取り、それらを0ターミネーターとともにstrに保存します。先頭の空白をスキップしません。最大文字数の前に改行(strに保存されます)またはEOF)が表示されると、停止します。

fscanf%s変換指定子を指定すると、先頭の空白がスキップされ、空白以外のすべての文字が読み取られ、strの後に0ターミネータが続きます。次の空白文字またはEOFで読み取りを停止します。明示的なフィールド幅がないと、ストリーム内にあるのと同じ数の非空白文字が読み取られ、ターゲットバッファをオーバーランする可能性があります。

したがって、入力ストリームが次のようになっていると想像してください:"\t abcdef\n<EOF>"fgetsを使用して読み取った場合、strには"\t abcdef\n\0"が含まれます。 fscanfを使用した場合、strには"abcdef\0"を含めることができます(\0は0ターミネーターを示します)。

2
John Bode

fgets行全体を読み取ります。 fscanf with %sスペース(または\ n、\ tなど)で区切って文字列を読み取ります。とにかく、読み取る配列が入力を含むのに十分な大きさであることが確実でない限り、それらを使用しないでください。あなたが書いた When changing the "10" in the fgets function the counter will always give different results. fgetsとscanfは、読み取るバイト数を認識していないことに注意してください。あなたは彼らに言うべきです。 「10」を変更すると、これらの関数が書き込むバッファが拡大されます。

1
asaelr