5

I have a device which sends me binary data of type uint32_t. I want to save the data to a binary file. Here is my code:

#include<iostream> #include<fstream> #include <cstdlib> using namespace std; int main() { ofstream myFile ("data2.bin", ios::out | ios::binary); bool buffer[32]; for (int k = 0; k<100; k++) { for (int i = 0; i<32;i++) { buffer[i] = (bool)rand()%2; } myFile.write ((char*)&buffer, 32); } myFile.close(); } 

It works, but the size of the file is 3.2 kB, not 0.4 kB. Moreover, when I try to read the data from the file (the data produced by my device), I get strange outcome, not in the format described in the manual. Of course, there is more data than I expect.

What am I doing wrong?

7
  • 7
    You're writing 100 times 32 bytes. Why do you think it should be 0.4kB? Am I missing something? --- Oh, I see... Commented Apr 20, 2015 at 19:23
  • 32 bools is 32 bytes normally. unit32 is a 32 bit data type that is 4 bytes at an 8 bit byte. Commented Apr 20, 2015 at 19:25
  • So, what's the safest way to write uint_32t to a binary file? Commented Apr 20, 2015 at 19:29
  • 1
    You didn't tell us what format you expected. Commented Apr 20, 2015 at 19:29
  • 2
    "As far as I know binary files use one bit for each boolean variable" Where did you hear that? Commented Apr 20, 2015 at 19:30

1 Answer 1

9

A bool takes one byte. Check sizeof(bool) and you'll find it equal to 1. So the array is 32 bytes long and you're writing it 100 times, therefore 3.2kB.

If you want to store a bit array, you need to use something different from an array of bool. You have a number of options:

  1. Use an array of bytes, integers, or anything whose size you know, and explicitly turn on the bits that you want. Then, store the array.

    #include <iostream> #include <fstream> #include <cstdlib> #include <cstdint> using namespace std; int main() { ofstream myFile ("data2.bin", ios::out | ios::binary); uint32_t buffer; for (int k = 0; k<100; k++) { buffer = 0; for (int i = 0; i<32; i++) { buffer <<= 1; buffer |= (bool)(rand()%2); } myFile.write((char*) &buffer, sizeof(buffer)); } myFile.close(); return 0; } 

    In fact, if you already have an array of uint32_t to begin with, then you don't need the loop and you can just store the array directly. Use the exact myFile.write line above, where buffer is your uint32_t array.

  2. Use a vector<bool> or preferably a bitset. Both are optimized and use one bit per element.

    #include <iostream> #include <fstream> #include <cstdlib> #include <bitset> using namespace std; int main() { ofstream myFile ("data2.bin", ios::out | ios::binary); bitset<32> buffer; for (int k = 0; k<100; k++) { for (int i = 0; i<32; i++) { buffer[i] = (bool)(rand()%2); } myFile.write((char*) &buffer, 32/8); } myFile.close(); return 0; } 

Of course, in both cases, you output bytes to your file. In the second case, the number of bits has to be a multiple of 8.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.