How to store a <bool> vector or bit set in a file, but bit-wise?
How to write bit data to a file?
The first answer does not answer the question correctly, since it takes 8 times more space than necessary.
How would you do that? I really need this to save a lot of true / false values.
, , , unsigned long, :: dynamic_bitset. ( , , 32 64 , ).
dynamic_bitset to_block_range . dynamic_bitset , from_block_range BlockInputIterator append().
(), .
"": , , , , . endianness (, ntohl, , , -endian, , , ).
(: , boost:: dynamic_bitset , . ).
, os.write( &data[0], sizeof(Block) * nBlocks ), . read( &data[0], sizeof(Block) * nBlocks ), vector<Block>, data.resize(nBlocks) (not reserve()). ( istream_iterator istreambuf_iterator, (), , ).
:
std::vector<bool> data = /* obtain bits somehow */
// Reserve an appropriate number of byte-sized buckets.
std::vector<char> bytes((int)std::ceil((float)data.size() / CHAR_BITS));
for(int byteIndex = 0; byteIndex < bytes.size(); ++byteIndex) {
for(int bitIndex = 0; bitIndex < CHAR_BITS; ++bitIndex) {
int bit = data[byteIndex * CHAR_BITS + bitIndex];
bytes[byteIndex] |= bit << bitIndex;
}
}
, , , - , . , , ( , , CHAR_BITS), , .
( , 1am, - ).
, , .
template<int I>
void bitset_dump(const std::bitset<I> &in, std::ostream &out)
{
// export a bitset consisting of I bits to an output stream.
// Eight bits are stored to a single stream byte.
unsigned int i = 0; // the current bit index
unsigned char c = 0; // the current byte
short bits = 0; // to process next byte
while(i < in.size())
{
c = c << 1; //
if(in.at(i)) ++c; // adding 1 if bit is true
++bits;
if(bits == 8)
{
out.put((char)c);
c = 0;
bits = 0;
}
++i;
}
// dump remaining
if(bits != 0) {
// pad the byte so that first bits are in the most significant positions.
while(bits != 8)
{
c = c << 1;
++bits;
}
out.put((char)c);
}
return;
}
template<int I>
void bitset_restore(std::istream &in, std::bitset<I> &out)
{
// read bytes from the input stream to a bitset of size I.
/* for debug */ //for(int n = 0; n < I; ++n) out.at(n) = false;
unsigned int i = 0; // current bit index
unsigned char mask = 0x80; // current byte mask
unsigned char c = 0; // current byte in stream
while(in.good() && (i < I))
{
if((i%8) == 0) // retrieve next character
{ c = in.get();
mask = 0x80;
}
else mask = mask >> 1; // shift mask
out.at(i) = (c & mask);
++i;
}
}
, , , reinterpret_cast , , , , , , (endianness?)