3

このコードは、行バッファリングに 10 バイトだけを割り当て、最初の行が 45 バイトのファイルを読み取ります。実行すると、プログラムは最初の 10 バイトだけでなく 45 バイトすべてを読み取ります

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *tst;
    tst = fopen("x.log","r");

    char *buff = malloc(10); //Just 10 characters
    setvbuf(tst, buff, _IOLBF, 10);

    char *mystring = malloc(45); //First line of x.log is 45 characters exactly
    if ( fgets (mystring, 45, tst) != NULL )
        puts(mystring);
    fclose (tst);
    free(buff);
}
4

4 に答える 4

3

fgets()getc()改行を読み取るか、指定された制限に達するまで、一度に 1 文字ずつ読み取るために、内部的に使用します。getc()が I/O バッファの最後に到達すると、バッファが再充填されるため、 で設定されたサイズに制限されませんsetvbuf()。小さなバッファ サイズを設定すると、効率が低下しますが、読み取ることができるデータの量は変わりません。

于 2013-10-26T10:37:17.813 に答える
1

なしとありの違いsetvbufは、

open("file.txt", O_RDONLY)              = 3
read(3, "Hickanckdnckncksckscskcnnacnckad"..., 4096) = 65

Vs

open("file.txt", O_RDONLY)              = 3
read(3, "Hickanckdn", 10)               = 10
read(3, "cknckscksc", 10)               = 10
read(3, "skcnnacnck", 10)               = 10
read(3, "adjsnccnad", 10)               = 10 
read(3, "ncacsjcadj", 10)               = 10

fgets()4096一度に大量のバイトを読み込みます。setvbuf制御する方法と、バッファの大きさですread

于 2013-10-26T10:47:24.650 に答える
1

setvbuf は、サイズ 10 のバッファーをファイルに関連付けます。

45 バイトすべてを読み取るのはなぜですか?

fgets を使用してファイルを読み取り、45 バイトを読み取ろうとしています。ファイル バッファのサイズは 10 (および _IOLBF オプション) であるため、読み取りは次のように行われます。

  1. ファイルからバイト 0 ~ 9 を mystring に読み取ります
  2. バイト 10 ~ 19 を読み取る...
  3. バイト 20 ~ 29 を読み取る...
  4. バイト 30 ~ 39 を読み取る...
  5. バイト 40 ~ 45 を読み取り、\n で停止します

デフォルトのバッファを使用して、おそらく一度にすべてのバイトを読み取る代わりに (バッファを再充填せずに)

于 2013-10-26T10:41:09.533 に答える
1
setvbuf(tst, buff, _IOLBF, csize * 10);

setvbuf の man ページによると、バッファリング モードを _IOLBF = Line Buffered に設定します。

setvbuf(tst, buff, _IOFBF, csize * 10);

10 バイトのみをバッファリングする必要がありますが、fgets は依然として行全体を読み取ります。

バッファリングとは、内部でデータがバッファに読み込まれることを意味し、バッファがいっぱいになるか、改行が読み取られるときにバッファリングされたインラインで、バッファが上書きされます。

于 2013-10-26T10:41:25.320 に答える