C++のiostream

簡単な実装例

というわけで、文字列を保持する stream を作ってみよう(strstring もどき)。

  • iostream を継承する。
  • 読み取りと書き込みの二つのバッファを持つ。
  • どちらのバッファも固定長、同一サイズで、拡張はしない。
  • flush() は現在書き込みバッファに書き込まれた部分を読み込みバッファにコピーした後、書き込みバッファをクリアする。

この仕様であれば、constructor と sync() のみを実装すればよい。iostream (実際には ostream)の flush() は streambuf の pubsync() を呼び出し、 省略時動作で pubsync() は限定公開メンバ関数 である sync() を呼び出すので。

まずはヘッダファイル mybuffer.h

#ifndef MYSTREAM_H_INCLUDED
#define MYSTREAM_H_INCLUDED

#include <iostream>

class mybuffer : public std::streambuf
{
public:
	mybuffer();
	virtual ~mybuffer();

protected:
	virtual int sync();

private:
	char m_wbuf[1024];
	char m_rbuf[1024];
};

#endif

続いて実装ファイル mystream.cpp

#include "mystream.h"

mybuffer::mybuffer()
{
 	setg(m_rbuf, m_rbuf, m_rbuf);
	setp(m_wbuf, m_wbuf + 1024);
}

mybuffer::~mybuffer()
{
}

int
mybuffer::sync()
{
	int n = pptr() - pbase();
	for(int i = 0; i < n; i++)
		m_rbuf[i] = m_wbuf[i];
	setg(m_rbuf, m_rbuf, m_rbuf + n);
	setp(m_wbuf, m_wbuf + 1024);
	return 0;
}

これで以下のようなテストプログラムが動く。

#include <iostream>
#include "mystream.h"

using namespace std;

int
main()
{
	mybuffer buf;
	iostream mystream(&buf);
	mystream.exceptions(ios_base::badbit);

	try
	{
		char c;
		while(cin.get(c))
			mystream.put(c);
		mystream.flush();

		while(mystream.get(c))
			cout.put(c);
	}
	catch(ios_base::failure& f)
	{
		cerr << "Exception " << f.what() << endl;
	}
	catch(...)
	{
		cerr << "Unknown exception" << endl;
	}
	return 0;
}

結局

が正確のようである。

というか、規格書(JIS X 3014:2003(ISO/IEC 14882:2003)) を 見ればよいだけの話だったかも知れない。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-01-09 (水) 17:42:16