basic_ostream::flush

flushは、バッファをフラッシュする。

basic_ostream::flush - cpprefjp C++日本語リファレンス

C言語のfflushのトピックのC++版である。
C言語では、'\n'など改行があるとフラッシュされるので、'\n'を出力せずにsleepさせた。
C++でも、std::endlなど改行があるとフラッシュされるので、std::endlを出力せずにsleepさせる。
で、そのsleepの前に、std::cout.flushでいったんフラッシュする。
こうすると、

実行時
実行時

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

5秒後
5秒後

5秒後に"str2"が出力される。

Sample/cpp/basic_ostream/flush/src/basic_ostream at master · bg1bgst333/Sample · GitHub

basic_ostream::write

writeは文字列(またはバイト列)を出力する。

basic_ostream::write - cpprefjp C++日本語リファレンス

stringオブジェクトのstrに"ABCDE"をセットし、writeの第1引数にはstr.c_str()でC言語形式で文字列を、第2引数にはstr.size()でサイズを渡す。

$ vi basic_ostream.cpp
$ g++ basic_ostream.cpp -o basic_ostream
$ ./basic_ostream
ABCDE$

改行はしないので、このように出力される。

Sample/cpp/basic_ostream/write/src/basic_ostream at master · bg1bgst333/Sample · GitHub

basic_string::c_str

C++のstring(basic_string)も時には、C言語の関数に渡したり、文字配列として扱う場合が度々あるだろう。
しかし、相手はC言語の仕様で作られている要素のため、そのまま渡すことはできない。

basic_string::c_str - cpprefjp C++日本語リファレンス

c_strは、stringオブジェクトの持つ文字列の先頭アドレスをC言語のconst char *で返してくれるメンバ関数
これを使えば、C言語の関数に渡したり、文字配列として扱ったりできる。

strの内容をstrcpyでbufにコピーしている。
strをそのまま渡せないので、str.c_str()として、文字配列の先頭ポインタを渡して、内容をコピーさせている。

$ g++ basic_string.cpp -o basic_string
$ ./basic_string
str = ABCDE
buf = ABCDE
$

bufにコピーできている。
C言語の関数、配列、と、C++のstringを同時に気軽に使える。

Sample/cpp/basic_string/c_str/src/basic_string at master · bg1bgst333/Sample · GitHub

basic_string::size

stringの正体は、

basic_string - cpprefjp C++日本語リファレンス

basic_string<char>であり、さまざまなメンバが定義されている。
sizeは、

basic_string::size - cpprefjp C++日本語リファレンス

文字列の長さを取得するメンバ関数

str1は後から"ABC"を代入、str2は初期化で"あいうえお"、str3は初期化で"かきくけこ"(stringにしているがbasic_string<char>と一緒。)をセットして、それぞれのサイズをsize()で取得している。

$ vi basic_string.cpp
$ g++ basic_string.cpp -o basic_string
$ ./basic_string
size1 = 3
size2 = 15
size3 = 15
$

utf-8環境なので、ここでは、英数字は1文字1バイト、日本語だと1文字3バイトになる。
文字数ではなく、文字列全体(NULL文字除く)にかかったサイズ(バイト数)を示しているのに注意。

Sample/cpp/basic_string/size/src/basic_string at master · bg1bgst333/Sample · GitHub

fflush

fflushは、バッファのフラッシュを行う。

Man page of FFLUSH
C言語関数辞典 - fflush

入出力バッファの内容をいったん出力して、バッファを空にすることをフラッシュという。
前回の例で、setbufでNULLをセットしてバッファリングしないようにしたが、バッファリングをしつつ、すぐに出力したい時もある場合は、この方法を使う。

"str1"を出力した後に、fflushでstdoutをフラッシュする。

実行直後
実行直後

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

5秒後
5秒後

5秒後に"str2"が出力される。

fflushの使いどころのサンプルがなかなかみつからなかったが、
c++ - Case(s) where output buffer won't flush? - Stack Overflow
ようやくみつかった・・・。

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

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

stdout

stdoutは標準出力ストリームを表すマクロで、実態は標準出力を指すファイルポインタ。

Man page of STDIN

fgetsで標準入力のstdinを使ったように、fputsで標準出力のstdoutを使ってみる。

fputsの第2引数にstdoutを指定する。
fputsは改行しないので、'\n'を入れるのを忘れずに。
(fputsは終端NULL文字も書き込まれないが、そこについては特にそれで問題なさそうに見える。)

$ vi stdout.c
$ gcc stdout.c -o stdout
$ ./stdout
ABCDE
$

このように標準出力に出力される。

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