我就是想写一个C++的bitstream类,可是为什么输入的时候就不行了

andalousie 发布于 2014/03/05 18:25
阅读 352
收藏 0
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>

class bitostream
{
	struct bit{
		unsigned b0:1; 
		unsigned b1:1; 
		unsigned b2:1; 
		unsigned b3:1; 
		unsigned b4:1; 
		unsigned b5:1; 
		unsigned b6:1; 
		unsigned b7:1; 
		bit() : _next(0) {};
		bit & operator=(unsigned char v)
		{
			b0 = (v & 0x01) > 0 ? 1 : 0;
			b1 = (v & 0x02) > 0 ? 1 : 0;
			b2 = (v & 0x04) > 0 ? 1 : 0;
			b3 = (v & 0x08) > 0 ? 1 : 0;
			b4 = (v & 0x10) > 0 ? 1 : 0;
			b5 = (v & 0x20) > 0 ? 1 : 0;
			b6 = (v & 0x40) > 0 ? 1 : 0;
			b7 = (v & 0x80) > 0 ? 1 : 0;
			return *this;
		}
		bit * _next;
	};
public:
	bitostream(std::string const & nameFile)
		: _stream(nameFile.c_str()), _head(0), 
		_byte(0), buffer(0), N(-1)
	{}
	~bitostream() { _stream.close(); }
	//OUTPUT
	void allocate();
	void writeChar(unsigned char v);
	void writeBool(bool b);
	void bitout();
private:
	std::ofstream _stream;
	bit * _head;
	bit * _byte;
	unsigned char buffer;
	int    N;
};

void bitostream::allocate()
{
	if(!_head)
	{
		bit * newByte = new bit;
		_head = newByte;
		_byte = newByte;
		* _byte = 0;
		buffer = 0;
	}
	else
	{
		_byte->_next = new bit;
		_byte = _byte->_next;
		* _byte = 0;
		buffer = 0;
	}
}

void bitostream::writeChar(unsigned char v)
{
	if(N == -1 || N == 8)
	{ allocate(); N=0; }
	if(!N)
	{
		N = 8;
		* _byte = v;
		return;
	}
	unsigned char tmp = v >> N;
	unsigned char pmt = v << (8-N);
	int save = N;
	buffer += tmp;
	N = 0;
	writeChar(buffer);
	N = -1;
	writeChar(pmt);
	N = save;
}

void bitostream::writeBool(bool b)
{
	if(N == -1 || N == 8)
	{ allocate(); N=0; }
	unsigned char tmp = b ? 1 : 0;
	tmp = tmp << (7-N);
	buffer += tmp;
	N++;
}

void bitostream::bitout()
{
	bit * outByte = _head;
	while(outByte)
	{
		_stream.write(reinterpret_cast<char *>(outByte), 1);
		outByte = outByte->_next;
	}
	_head = 0;
	_byte = 0;
	buffer = 0;
}

class bitistream
{
public:
	bitistream(std::string const & nameFile)
		: _stream(nameFile.c_str()), inbuf(0), inN(0)
	{
		if(!_stream.is_open())
			throw "couldn't open file";
		pbuf = _stream.rdbuf();
	}
	~bitistream() { _stream.close(); }
	//INPUT
	void get_in();
	char readChar();
	bool readBool();
public:
	std::ifstream _stream;
	std::streambuf * pbuf;
	unsigned char  inbuf;
	int    inN;
};

void bitistream::get_in()
{
	if(pbuf->sgetc() != EOF)
		inbuf = pbuf->sbumpc();
}

char bitistream::readChar()
{
	if(!inN || inN == 8)
	{
		get_in();
		inN = 0;
		return inbuf;
	}
	unsigned char tmp = inbuf << inN;
	inbuf = 0;
	unsigned char pmt = inbuf >> (8-inN);
	tmp += pmt;
	return tmp;
}

bool bitistream::readBool()
{
	if(!inN || inN == 8)
	{
		get_in();
		inN = 0;
	}
	unsigned char tmp = inbuf << inN;
	inN++;
	return (tmp & 0x80)>0;
}

int main()
{
	bitostream bin("huff.trie");
	bin.writeBool(true);
	bin.writeChar('r');
	bin.bitout(); 
	bitistream by("huff.trie");
	std::cout << by.readBool();
	std::cout << by.readBool();
	std::cout << by.readBool();
	std::cout << by.readBool();
	std::cout << by.readBool();
	std::cout << by.readBool();
	std::cout << by.readBool();
	std::cout << by.readBool();
	return 0;
}

这一段是我的程序,为什么,std::streambuf * pbuf的pbuf->sgetc != EOF会出问题??正确结果应该是把10111001输出出来就对了……

还有,这儿有一段别人的代码,可以读我的huff.trie文件,为什么我的不行?

// show file content - sbumpc() example
#include <iostream>     // std::cout, std::streambuf
#include <fstream>      // std::ifstream
#include <cstdio>       // EOF

int main () {
  std::ifstream istr ("huff.trie");
  if (istr) {
    std::streambuf * pbuf = istr.rdbuf();
    while ( pbuf->sgetc() != EOF )
    {
      unsigned char ch = pbuf->sbumpc();
      std::cout << ch;
    }
    istr.close();
  }
  return 0;
}





加载中
0
z
zhoutianzuo
void bitostream::bitout()
{
    bit * outByte = _head;
    while(outByte)
    {
        _stream.write(reinterpret_cast<char *>(outByte), 1);
        outByte = outByte->_next;
    }
    _head = 0;
    _byte = 0;
    buffer = 0;
    _stream.flush();
}
0
a
andalousie
谢谢解决了问题,不过我要输出01010000010010100010001000010101010000110101010010101000010的时候,输出了01010000 00001010 00000010 01000010 01000011 01010100 00101000 01000000,看来输出还是有问题的。
z
zhoutianzuo
记得我08年的时候在csdn上面扫荡帖子的时候,很多人都是直接要代码的。 小伙不错,加油
0
a
andalousie

我改出来了,如果大家有用得着的我这段代码的地方,随便用哦。开源嘛,嘻嘻。

#if !defined BITSTREAM
#define BITSTREAM
//Alexander Misel 2013, Oschina
//Open Source, free to copy

#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>

class bitostream
{
	struct bit{
		bit() : _next(0) {};
		bit & operator=(unsigned char v)
		{
			_bit = v;
			return *this;
		}
		unsigned char _bit;
		bit * _next;
	};
public:
	bitostream(std::string const & nameFile)
		: _stream(nameFile.c_str(), std::ios::binary), 
		_head(0), _byte(0), buffer(0), N(-1)
	{}
	~bitostream() { _stream.close(); }
	//OUTPUT
	void allocate();
	void writeChar(unsigned char v);
	void writeBool(bool b);
	void bitout();
private:
	std::ofstream _stream;
	bit * _head;
	bit * _byte;
	unsigned char buffer;
	int    N;
};

void bitostream::allocate()
{
	if(!_head)
	{
		bit * newByte = new bit;
		_head = newByte;
		_byte = newByte;
		* _byte = 0;
		buffer = 0;
	}
	else
	{
		_byte->_next = new bit;
		_byte = _byte->_next;
		* _byte = 0;
		buffer = 0;
	}
}

void bitostream::writeChar(unsigned char v)
{
	if(N == -1 || N == 8)
	{ allocate(); N=0; }
	if(!N)
	{
		N = 8;
		* _byte = v;
		return;
	}
	unsigned char tmp = v >> N;
	unsigned char pmt = v << (8-N);
	int save = N;
	buffer += tmp;
	N = 0;
	writeChar(buffer);
	N = -1;
	writeChar(pmt);
	buffer = pmt;
	N = save;
}

void bitostream::writeBool(bool b)
{
	if(N == -1 || N == 8)
	{ allocate(); N=0; }
	unsigned char tmp = b ? 1 : 0;
	tmp = tmp << (7-N);
	buffer += tmp;
	if(N == 7)
	{
		int save = N;
		N = 0;
		writeChar(buffer);
		N = save;
	}
	N++;
}

void bitostream::bitout()
{
	bit * outByte = _head;
	while(outByte)
	{
		_stream.write(reinterpret_cast<char *>(outByte), 1);
		outByte = outByte->_next;
	}
	_head = 0;
	_byte = 0;
	buffer = 0;
	_stream.flush();
}

class bitistream
{
public:
	bitistream(std::string const & nameFile)
		: _stream(nameFile.c_str(), std::ios::binary), 
		inbuf(0), inN(0), id(0)
	{
		if(!_stream.is_open())
			throw "couldn't open file";
		pbuf = _stream.rdbuf();
	}
	~bitistream() { _stream.close(); }
	//INPUT
	void get_in();
	unsigned char readChar();
	bool readBool();
public:
	std::ifstream _stream;
	std::streambuf * pbuf;
	unsigned char  inbuf;
	int    inN;
	int    id;
};

void bitistream::get_in()
{
	if(pbuf->sgetc() != EOF)
		inbuf = pbuf->sbumpc();
}

unsigned char bitistream::readChar()
{
	if(!inN || inN == 8)
	{
		get_in();
		inN = 0;
		return inbuf;
	}
	unsigned char tmp = inbuf << inN;
	inbuf = 0;
	get_in();
	unsigned char pmt = inbuf >> (8-inN);
	tmp += pmt;
	return tmp;
}

bool bitistream::readBool()
{
	if(!inN || inN == 8)
	{
		get_in();
		id++;
		inN = 0;
	}
	unsigned char tmp = inbuf << inN;
	inN++;
	return (tmp & 0x80)>0;
}

#endif

返回顶部
顶部