用C++编写二进制文件

use*_*748 5 c++ binary

我有一个设备向我发送类型为uint32_t的二进制数据.我想将数据保存到二进制文件.这是我的代码:

#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();
}
Run Code Online (Sandbox Code Playgroud)

它工作,但文件的大小是3.2 kB,而不是0.4 kB.此外,当我尝试从文件中读取数据(我的设备生成的数据)时,我得到了奇怪的结果,而不是手册中描述的格式.当然,有比我预期更多的数据.

我究竟做错了什么?

nic*_*kie 9

A bool需要一个字节.检查sizeof(bool),你会发现它等于1.所以数组是32字节长,你写100次,因此3.2kB.

如果要存储位数组,则需要使用与数组不同的内容bool.你有很多选择:

  1. 使用字节数组,整数或您知道其大小的任何内容,并显式打开您想要的位.然后,存储数组.

    #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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    实际上,如果你已经有一个数组uint32_t,那么你不需要循环,你可以直接存储数组.使用myFile.write上面的确切行,buffer您的uint32_t数组在哪里.

  2. 使用vector<bool>或优选a bitset.两者都经过优化,每个元素使用一位.

    #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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

当然,在这两种情况下,都会将字节输出到文件中.在第二种情况下,位数必须是8的倍数.