0

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.

tdfoster
  • 3
  • 3
  • 2
    `std::bitset` might help you. – chris May 15 '13 at 21:57
  • You could use bitmasking to extract every bit from each byte you read. – Etherealone May 15 '13 at 21:59
  • @chris: Not really. He would still have to read a file byte by byte, and I don't see convenient conversion to `bitset` from there. – Alexander Shukaev May 15 '13 at 21:59
  • Will this help: http://stackoverflow.com/questions/708114/convert-byte-array-into-bitset – Ferry van den heuvel May 15 '13 at 22:00
  • I current accept text input from the terminal for the program and use bitset for that, but I would like to be able to accept a file (not necessarily text) instead of terminal input. – tdfoster May 15 '13 at 22:02
  • 1
    What's the difference? Bytes from string or bytes from file are still bytes. Just read them and accommodate them into `bitset` properly, as already provided in the link. – Alexander Shukaev May 15 '13 at 22:04
  • 1
    Some context would help here... bytes are made of bits, you have the bytes you have the bits, bits will be stored in bytes no matter what you try. If you want to get the bits mask the byte. – Serdalis May 15 '13 at 22:09
  • What does the file itself look like ? Is it raw binary or an encoding of some sort ? I would probably design it along the lines of vector and use a generic copy() from ifstream to vector ... – AlexK May 15 '13 at 22:11
  • the file will most likely be an image. Basically I want to open the file, convert it to binary, do some DSP so I can transmit it wirelessly, then receive and open the image. This works with text, but I want to be able to read a file in. – tdfoster May 15 '13 at 22:16
  • There is no primitive "array of bits" construct in C/C++. You can either use a struct/class or do your own bit twiddling. – Hot Licks May 15 '13 at 22:51
  • (And if it's an image file it's almost certainly viewed as an array of bytes, not bits.) – Hot Licks May 15 '13 at 22:52

2 Answers2

0

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;
}
paddy
  • 60,864
  • 6
  • 61
  • 103
  • 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. – paddy May 15 '13 at 22:47
0
#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:

http://ideone.com/Is7xRy

notes:

  • bitset size 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 istringstream by ifstream appropriately .
oblitum
  • 11,380
  • 6
  • 54
  • 120