C++でメモリストリームを扱う方法
C++はファイルストリームやストリングストリームはあるのに、何故かメモリストリームが存在しない!!!
今回はストリングストリームをメモリストリームとして扱う方法を紹介する。
まずは出力ストリームの使い方だ。
#include <iostream> #include <sstream> #include <vector> int main() { // データの書き込み char n[] = { 1, 3, 0, 4, 13, }; // 書き込むデータを用意 std::ostringstream os; // 書き込みインスタンスを作成 os.write(n, sizeof(n)); // データを書き込む // 書き込んだデータの取得 std::vector<char> buf(os.str().size()); // ストリームのサイズ分の領域を確保 memcpy(&buf[0], os.str().data(), os.str().size()); // バッファにコピー // コピーしたデータを確認 for (auto it = buf.begin(); it != buf.end(); ++it) { std::cout << static_cast<int>(*it) << " "; } }
出力結果は以下となる。
1 3 0 4 13
ここまでは特に問題ないだろう。
ストリングバッファにバイナリを書き込むのが少し抵抗があるが、機能が存在しないのだから仕方ない。
次は入力ストリームである。こいつが曲者だ。
まずは次のプログラムを見て欲しい。
#include <iostream> #include <sstream> #include <vector> int main() { // データの書き込み char n[] = { 1, 3, 0, 4, 13, }; // 書き込むデータを用意 std::istringstream is(n, sizeof(n)); // インスタンスを作成し、同時に書き込む // 書き込んだデータを確認する std::string& ss = is.str(); for (auto it = ss.begin(); it != ss.end(); ++it) { std::cout << static_cast<int>(*it) << " "; } }
出力結果は以下となる。
1 3
書き込んだバイナリデータの中にナル文字が入っていた場合、そこで書き込みが中断されてしまう。
次のプログラムはこの問題を回避する。
#include <iostream> #include <sstream> #include <vector> int main() { // データの書き込み char n[] = { 1, 3, 0, 4, 13, }; // 書き込むデータを用意 std::string s(n, n + sizeof(n)); // バイナリから文字列を生成(STLのbegin()とend()の指定方法) std::istringstream is(s, std::istringstream::binary); // インスタンスをバイナリ指定で生成 // 書き込んだデータを確認する std::string& ss = is.str(); for (auto it = ss.begin(); it != ss.end(); ++it) { std::cout << static_cast<int>(*it) << " "; } }
出力結果は以下となる。
1 3 0 4 13
この方法を使うことで入力ストリームでバイナリを扱うことが可能となる。