Namespaces
Variants

setvbuf

ja.cppreference.net より
< c | io
 
 
ファイル入出力
型とオブジェクト
        
関数
ファイルアクセス
(C95)
書式なし入出力
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

書式付き入力
直接入出力
書式付き出力
ファイル位置決め
エラーハンドリング
ファイル操作
 
ヘッダで定義 <stdio.h>
int setvbuf( FILE* stream, char* buffer,
             int mode, size_t size );
(C99 まで)
int setvbuf( FILE* restrict stream, char* restrict buffer,
             int mode, size_t size );
(C99 以降)
#define _IOFBF     /* unspecified */
#define _IOLBF     /* unspecified */
#define _IONBF     /* unspecified */

指定されたファイルストリーム stream のバッファリングモードを引数 mode に従って変更します。さらに、

  • もし buffer がヌルポインタの場合、内部バッファを size にリサイズします。
  • もし buffer がヌルポインタでない場合、ストリームにサイズ size のユーザ提供バッファを先頭アドレス buffer で使用するように指示します。ストリームは (fclose) でクローズする必要があり、生存期間 が指す配列の buffer が終了します。 の呼び出し成功後setvbuf、配列の内容は不定であり、それを用いる動作は未定義です。

パラメータ

stream - バッファを設定するファイルストリーム
buffer - ストリームが使用するバッファへのポインタ、またはサイズとモードのみを変更する場合はnullポインタ
mode - 使用するバッファリングモード。以下の値のいずれかを指定:
_IOFBF 完全バッファリング
_IOLBF 行バッファリング
_IONBF バッファリングなし
size - バッファのサイズ

戻り値

​ 0 ​ 成功時は0、失敗時は0以外の値を返します。

ノート

この関数は、streamが開かれたファイルに関連付けられた後、かつ他の操作(setbuf/setvbufの失敗した呼び出しを除く)の前にのみ使用できます。

すべてのsizeバイトがバッファリングに使用されるわけではありません。実際のバッファサイズは通常、2の倍数やページサイズの倍数などに切り捨てられます。

多くの実装では、行バッファリングは端末入力ストリームに対してのみ利用可能です。

よくある間違いは、stdinやstdoutのバッファを、プログラムの終了前に寿命が尽きる配列に設定することです:

int main(void)
{
    char buf[BUFSIZ];
    setbuf(stdin, buf);
} // lifetime of buf ends, undefined behavior

デフォルトのバッファサイズBUFSIZは、実装におけるファイルI/Oに最も効率的なバッファサイズであると期待されていますが、POSIX fstatの方がより良い推定値を提供することがよくあります。

例

バッファサイズを変更するユースケースの一つは、より適切なサイズが分かっている場合です。(この例では、一部のPOSIX関数(例:fileno)を使用しています。SO: #1 および #2 も参照してください)。

// Make some POSIX functions, such as ‘int fileno(FILE*)’, visible:
#define _POSIX_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main(void)
{
    FILE* fp = fopen("/tmp/test.txt", "w+");
    if (fp == NULL)
    {
        perror("fopen");
        return EXIT_FAILURE;
    }

    struct stat stats;
    if (fstat(fileno(fp), &stats) == -1) // POSIX only
    {
        perror("fstat");
        return EXIT_FAILURE;
    }

    printf("BUFSIZ is %d, but optimal block size is %ld\n", BUFSIZ, stats.st_blksize);
    if (setvbuf(fp, NULL, _IOFBF, stats.st_blksize) != 0)
    {
        perror("setvbuf failed"); // POSIX version sets errno
        return EXIT_FAILURE;
    }

    int ch;
    while((ch=fgetc(fp)) != EOF); // read entire file: use truss/strace to
                                  // observe the read(2) syscalls used
    fclose(fp);
    return EXIT_SUCCESS;
}

出力例:

BUFSIZ is 8192, but optimal block size is 65536

参考文献

  • C23 規格 (ISO/IEC 9899:2024):
  • 7.21.5.6 setvbuf 関数 (ページ: 未定)
  • C17 規格 (ISO/IEC 9899:2018):
  • 7.21.5.6 setvbuf 関数 (ページ: 225)
  • C11 規格 (ISO/IEC 9899:2011):
  • 7.21.5.6 setvbuf 関数 (ページ: 308)
  • C99 規格 (ISO/IEC 9899:1999):
  • 7.19.5.6 setvbuf 関数 (ページ: 273-274)
  • C89/C90 規格 (ISO/IEC 9899:1990):
  • 4.9.5.6 setvbuf 関数

関連項目

ファイルストリームのバッファを設定する
(関数)