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ループの文字列の長さも説明できますか?
関数fgets
は、改行まで読み取ります(また、改行します)。 fscanf
と%s
指定子は空白スペースまで読み取り、それを格納しません。
ちなみに、scanfでバッファのサイズを指定していないため、安全ではありません。試してください:
fscanf(ptr, "%9s", str)
fgets
は改行を読み取ります。 fscanf
は空白までしか読み取りません。
あなたの例では、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ターミネーターを示します)。
fgets
行全体を読み取ります。 fscanf
with %s
スペース(または\ n、\ tなど)で区切って文字列を読み取ります。とにかく、読み取る配列が入力を含むのに十分な大きさであることが確実でない限り、それらを使用しないでください。あなたが書いた When changing the "10" in the fgets function the counter will always give different results.
fgetsとscanfは、読み取るバイト数を認識していないことに注意してください。あなたは彼らに言うべきです。 「10」を変更すると、これらの関数が書き込むバッファが拡大されます。