0

My objective is to read in data from a binary file and ultimately store the bits in 32bit slices. I have found a few different methods of reading binary in C++ but am not sure which is the best option and my main issue is that when outputting the data after having stored it I am not accessing individual bits but am displaying ASCII characters it seems.

int main(int argc, const char *argv[])
{

std::vector<char> memblock;
int i=0;
        ::std::ifstream in(argv[1], ::std::ios::binary);
        while (in) {
              char c;
              in.get(c);
              if (in) {
                 memblock.push_back(int(c));
                i++;
                  //::std::cout << "Read a " << int(c) << "\n";
              }
           }
std::cout << "The contents of memblock are:";
  for (std::vector<char>::iterator it = memblock.begin(); it != memblock.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
return 0;
}

And also:

streampos size;
      char * memblock;

      ifstream file ("path", ios::in|ios::binary|ios::ate);
      if (file.is_open())
      {
        size = file.tellg();
        memblock = new char [size];
        file.seekg (0, ios::beg);
        file.read (memblock, size);
        file.close();

        cout << "the entire file content is in memory";

       for(int i =0; i<10; i++){
           cout << memblock[i+2000];
       }
      }

Is there an advantage to each approach? Or is there an even better method? Also how do I make sure to store the actual bit values or binary data from the binary file? Thank you

John Smith
  • 283
  • 2
  • 19

2 Answers2

2

You want to be reading 32bit integers, not char:

uint32_t * memblock;
ifstream file ("path", ios::in|ios::binary|ios::ate);
   if (file.is_open())
   {
       size = file.tellg();
       memblock = new unit32_t [size / 4 + (size % 4 == 0 ? 0 : 1)];
       file.seekg (0, ios::beg);
       file.read (reinterpret_cast<char*>(memblock), size);
       file.close();

       cout << "the entire file content is in memory";

       for(int i =0; i<size/4; i++){
            cout << memblock[i];
       }
    }
Paul Evans
  • 27,315
  • 3
  • 37
  • 54
1

You are reading the actual binary content. Printing it via cout yields ascii characters because cout is designed for printing strings when passing char values unless told otherwise. Also if you want to store it in 32bit slices you should not use char but a 32bit datatype instead. Try uint32_t. Don't forget to adjust the size then since file size is given in bytes but uint32_t has four bytes.

In order to test whether the Nth bit (where N starts at 0) is set in some integer variable you could define the following macro:

#define IS_BIT_SET(v, N) ( (v) & ( 1<<(N) ) )
bool bit12Set = IS_BIT_SET(v, 12);

Or use std::bitset if you need more comfort.

jasal
  • 1,044
  • 6
  • 14
  • Thank you, is there a way to directly print the bits then? Or a way to access individual bits? – John Smith Jun 04 '14 at 14:33
  • 1
    If you want to inspect bits individually you'd have to use the bitwise operators together with masking. – jasal Jun 04 '14 at 14:37