I am trying to open a file into an array of bits (0,1) in C++. Every example I have seen has been working with has bytes, but I really need the actual bits. Is there an easy way to do this? The file will be <100 kB.
2 Answers
One of the problems with std::bitset is you have to template the size. You can just read it in manually though...
char c;
vector<char> bytes;
int nread = 0;
while( in.get(c) )
{
if( nread == 0 ) bytes.push_back(0);
bytes.back() = (bytes.back() << 1) | (c ? 1 : 0);
nread = (nread + 1) % 8;
}
1 Comment
paddy
On reflection, I may have misunderstood your intent. It seemed like you had a file of 0/1 values that you wanted to read into bits.
#include <bitset>
#include <sstream>
#include <iostream>
#include <cinttypes>
namespace my
{
template<size_t S>
std::istream &operator >> (std::istream &is, std::bitset<S> &bits)
{
std::uint8_t byte;
size_t i = 0;
while(i < S && (is >> byte))
for(size_t j = 0; j < 8 && i < S; ++j)
bits[i++] = (byte >> j) & 1;
return is;
}
}
int main()
{
constexpr size_t bytes = 2;
std::string bit_string("\x00\xFF", bytes);
std::istringstream bit_stream(bit_string);
std::bitset<8 * bytes> b;
{
using namespace my;
bit_stream >> b;
}
std::cout << b << std::endl;
for(size_t i = 0; i < b.size(); ++i)
std::cout << b[i];
std::cout << std::endl;
}
output:
1111111100000000
0000000011111111
run live:
notes:
bitsetsize is a non-type template parameter. You can't set it at runtime. So, this will only work with preallocation of the bitset and you'll get 0 padding for a larger bitset.- If you want a runtime sized bitset, check out boost::dynamic_bitset.
- The sample is expected to work for files just by replacing
istringstreambyifstreamappropriately .
std::bitsetmight help you.bitsetfrom there.bitsetproperly, as already provided in the link.