setbuf

setbufは、入出力バッファを設定するのに使う。

Man page of SETBUF
C言語関数辞典 - setbuf

printf、scanf、fprintf、fscanf、などの標準入出力、ファイル入出力関数は、そのまま入出力してるわけではなく、バッファにいったん貯めてから、出力する。
(これをバッファリングという。)
setbufは、指定したストリームで、自ら用意したバッファをバッファリングに使うようにセットする。
また、NULLをセットすることで、バッファリングしないようにもできる。

/* ヘッダファイルのインクルード */
#include <stdio.h> /* 標準入出力 */
#include <unistd.h> /* UNIX標準 */

/* main関数の定義 */
int main(void){

  /* 1つ目の文字列を出力. */
  printf("str1"); /* "str1"と改行なしで出力. */

  /* 5秒スリープ */
  sleep(5); /* sleepで5秒待つ. */

  /* 2つ目の文字列を出力. */
  printf("str2"); /* "str2"と改行なしで出力. */

  /* プログラムの終了 */
  return 0; /* 0を返して正常終了. */

}

例えば、このようなプログラムでは、"str1"が出力されてから、5秒経ち、そのあと"str2"が出力されると想像するかもしれない。
しかし、

実行直後
実行直後

実際には、"str1"が出力されずにsleepに入ってしまい、

5秒後
5秒後

5秒後に"str1"と"str2"が合わせて出力される。
バッファリングされるが出力されないという例。(意外とこれを扱ってる記事あまり無い。)

"str1"を即時出力したい場合は、setbufでstdoutにNULLを指定して、バッファリングしないようにすればいい。

こうすると、

実行直後
実行直後

実行直後に"str1"が出力され、

5秒後
5秒後

5秒後に"str2"が出力される。
(バッファをセットする例があまり思いつかなかったので、今回はこうしてみた。)

Sample/c/setbuf/setbuf/src/setbuf at master · bg1bgst333/Sample · GitHub