istringstream

入力用のistringstreamにおいて、入力演算子を使って、スペース区切りの文字列を、各トークン毎に変数に振り分けることができる。

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

istringstreamのissのコンストラクタに"ABC 123 0.456"を指定。
文字列、整数値、浮動小数値という形で、一気に取り出していく。

$ vi istringstream.cpp
$ g++ istringstream.cpp -o istringstream
$ ./istringstream
str = ABC
i = 123
f = 0.456
$

このように、各変数に振り分けられた。

Sample/cpp/istringstream/istringstream/src/istringstream at master · bg1bgst333/Sample · GitHub

ostringstream

文字列ストリームについては、strstreamが非推奨のため、現在ではstringstreamを使うのが一般的。
今回は、出力用のostringstreamで、簡単な出力の仕方を扱う。

std::basic_ostringstream - cppreference.com

ostringstreamのossは、コンストラクタでバッファを受け取らずに、動的バッファとする。
そして、次々と、文字列、整数値、浮動小数値をossに出力する。

$ vi ostringstream.cpp
$ g++ ostringstream.cpp -o ostringstream
$ ./ostringstream
oss.str() = ABC1230.456
$

このように、ossは文字列として全部くっついて出力される。

Sample/cpp/ostringstream/ostringstream/src/ostringstream at master · bg1bgst333/Sample · GitHub

strstream::str

strstreamで紐付けられたバッファにアクセスするには、メンバ関数str()を使う。

std::strstream::str - cppreference.com

今回は、紐付けたbufに続いて、str()で取得した文字列も出力する。

これで実行すると、

$ vi strstream.cpp
$ g++ strstream.cpp -o strstream
In file included from /usr/include/c++/8/backward/strstream:50,
                 from strstream.cpp:4:
/usr/include/c++/8/backward/backward_warning.h:32:2: 警告: #warning This
file includes at least one deprecated or antiquated header which may
be removed without further notice at a future date. Please use a
non-deprecated interface with equivalent functionality instead. For a
listing of replacement headers and interfaces, consult the file
backward_warning.h. To disable this warning use -Wno-deprecated.
[-Wcpp]
 #warning \
  ^~~~~~~
$ ./strstream
buf = ABC
ss.str() = ABC
$

このように、どちらも"ABC"が出力されている。

Sample/cpp/strstream/str/src/strstream at master · bg1bgst333/Sample · GitHub

ends

strstreamでNULL終端していない場合は、endsを出力することでNULL終端する。

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

前回のプログラムに、endsの処理を追加する。

このようにする。

$ vi ends.cpp
$ g++ ends.cpp -o ends
In file included from /usr/include/c++/8/backward/strstream:50,
                 from ends.cpp:4:
/usr/include/c++/8/backward/backward_warning.h:32:2: 警告: #warning This
file includes at least one deprecated or antiquated header which may
be removed without further notice at a future date. Please use a
non-deprecated interface with equivalent functionality instead. For a
listing of replacement headers and interfaces, consult the file
backward_warning.h. To disable this warning use -Wno-deprecated.
[-Wcpp]
 #warning \
  ^~~~~~~
$ ./ends
buf = ABC
$

今度は、"ABC"で終わっている。

Sample/cpp/ends/ends/src/ends at master · bg1bgst333/Sample · GitHub

strstream

文字列をストリームのように扱えるクラスがstrstream

std::strstream - cppreference.com

入出力演算子で、文字列を追加したりできる。

(ただし、随分前から非推奨になっているので、
basic_istringstream - cpprefjp C++日本語リファレンス
現在では、こちらを使うべきである。)

コンストラクタにバッファを指定すれば、そのバッファを使うし、そうでなければ動的にバッファを用意する。
今回は、自前でバッファを用意する。

bufを全て'X'で埋める。
そのbufをssに指定する。
ssに"ABC"を出力する。
ssをそのまま出力できないので、紐付いているbufを出力。

$ vi strstream.cpp
$ g++ strstream.cpp -o strstream
In file included from /usr/include/c++/8/backward/strstream:50,
                 from strstream.cpp:4:
/usr/include/c++/8/backward/backward_warning.h:32:2: 警告: #warning This
file includes at least one deprecated or antiquated header which may
be removed without further notice at a future date. Please use a
non-deprecated interface with equivalent functionality instead. For a
listing of replacement headers and interfaces, consult the file
backward_warning.h. To disable this warning use -Wno-deprecated.
[-Wcpp]
 #warning \
  ^~~~~~~
$ ./strstream
buf = ABCXXXXXXX��    ��
$

非推奨なので警告が出ている。
そして、なんとNULL終端されていない。
(Xの並びの最後ではなく、ABCの後ろがNULL終端されていないということ。)

Sample/cpp/strstream/strstream/src/strstream at master · bg1bgst333/Sample · GitHub

endl

C++において、改行などの入出力制御操作は、endlを始めとするマニピュレータが行う。

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

endlは改行を表すマニピュレータだが、その正体は関数テンプレートである。
引数にストリームを指定すると、そのストリームで改行が行われるというのが、直接的な操作。
ただし、一般的に使われるのは、basic_ostreamの出力演算子の、endlの関数ポインタを引数に取る演算子オーバーロードが呼ばれ、その中で改行が行われるというものである。

1つ目は、endlなしで改行。
2つ目は、"FGHIJ"の出力時点では改行されないが、endlの引数にcoutを渡すと、この時点で改行される。
3つ目は、endlを関数ポインタと見立てて、出力演算子オーバーロードで改行されている。

$ vi endl.cpp
$ g++ endl.cpp -o endl
$ ./endl
ABCDE
FGHIJ
KLMNO
$

どれも改行されてる。

Sample/cpp/endl/endl/src/endl at master · bg1bgst333/Sample · GitHub

basic_ios::fail

basic_ios::failは、エラー(failまたはbad)かどうかを判定する。

basic_ios::fail - cpprefjp C++日本語リファレンス

EOFとエラーは独立してるので、EOFであっても、エラーでないということはある。

eof()とは別にfail()でも調べる。

$ vi basic_ios.cpp
$ g++ basic_ios.cpp -o basic_ios
$ ./basic_ios
s: abcde
s = abcdeFGHIJ
good
$ ./basic_ios
s: xyzs = xyzDEFGHIJ
!
EOF
fail
$

ただ、この3文字の場合、EOFかつfailとなる。
これは、basic_istream::readの特徴で、文字数に達せずにEOFだとfailがtrueになるという仕様。

Sample/cpp/basic_ios/fail/src/basic_ios at master · bg1bgst333/Sample · GitHub