用C++编写二进制文件

5

我有一个设备,会向我发送 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();
}

虽然程序能够运行,但是文件大小为3.2 KB,而不是0.4 KB。此外,当我试图读取从设备生成的数据文件时,输出结果与手册描述的格式不同,产生了一些奇怪的结果。显然,数据量比我预期的要多。

我做错了什么?


7
你正在写入100次32字节。你为什么认为应该是0.4KB?我有所遗漏吗?---哦,我明白了... - nickie
1
你没有告诉我们你期望的格式。 - Lightness Races in Orbit
2
据我所知,二进制文件为每个布尔变量使用一个位。你从哪里听说的? - Lightness Races in Orbit
你知道你可以通过检查RAND_MAX,然后直接写入rand()的结果来节省时间,这样做大约100次吗? - Mooing Duck
顺便说一下:只有一些愚蠢的操作系统会识别“ ios :: binary”-其他操作系统会忽略它。 - user2249683
显示剩余2条评论
1个回答

9
一个 bool 占用一个字节。检查 sizeof(bool),你会发现它等于1。因此,这个数组长度为32字节,你正在写入它100次,因此总共是3.2KB。
如果你想存储位数组,需要使用与 bool 数组不同的东西。你有几个选择:
  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;
    }
    

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接