C++正在将位集写入二进制文件
C++ Writing bitset to binary file
希望这里有人能帮忙。我的问题如下:
我正在创建包含二进制数据的文件。在每个文件的开头是一个二进制标头,该标头具有关于文件内容的信息。文件头是一个固定大小的52字节。报头在报头内的特定字节偏移处具有特定的信息片段,然而一些信息片段仅覆盖字节的部分,例如3比特。
例如:
字节1-4=文件长度
字节5-8=标头长度
字节8-9=版本信息
字节10-13=文件创建时间戳
位1-4=月(1-12)
bit 5-9=第(1-31)天
bit 10-14=小时(0-23)
位15-20=分钟(0-59)
位21=UTC偏移方向
位22-26=UTC偏移小时
位27-32=UTC偏移分钟
等等。。。
有些值是静态定义的,有些是在运行时确定的。我试图做的是创建一个标头的"映射",定义一个属性必须使用的位数,以及由这些位数表示的值。这些存储在int对的向量中,int_pair.first是值,int_pair.second是位数。然后,我将提供的值(所有整数)转换为二进制格式,并将二进制表示法插入字符串流中。然后,我从二进制值的字符串表示中创建一个位集,并将其写入文件。我的问题是字节没有按正确的顺序显示在输出文件中。
在我的例子中,我将省略获取值的方法,只提供整数,为了简洁起见,我将截断标题中的一些信息(所以在这个例子中,标题是14字节,而不是52字节),但我大致要做的是:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <bitset>
#include <vector>
#include <algorithm>
int main ()
{
vector<pair<int,int>> header_vec;
header_vec.push_back(make_pair(9882719,32)); // file length
header_vec.push_back(make_pair(52,32)); // header length
header_vec.push_back(make_pair(6,3)); // high release identifier
header_vec.push_back(make_pair(4,5)); // high version identifier
header_vec.push_back(make_pair(6,3)); // low release identifier
header_vec.push_back(make_pair(4,5)); // low version identifier
// file open timestamp
header_vec.push_back(make_pair(9,4)); // month
header_vec.push_back(make_pair(6,5)); // day
header_vec.push_back(make_pair(19,5)); // hour
header_vec.push_back(make_pair(47,6)); // min
header_vec.push_back(make_pair(0,1)); // utc direction
header_vec.push_back(make_pair(0,5)); // utc offset hours
header_vec.push_back(make_pair(0,6)); // utc offset minutes
ostringstream oss;
// convert each integer to binary representation
for ( auto i : header_vec )
{
for (unsigned int j(i.second-1); j != -1; --j)
{
oss << ((i.first &(1 << j)) ? 1 : 0);
}
}
// copy oss
string str = oss.str();
// create bitset
bitset<112> header_bits(string(str.c_str()));
// write bitset to file
ofstream output("header.out", ios::out | ios::binary );
output.write( reinterpret_cast<char *>(&header_bits), 14);
output.close();
return 0;
}
现在,在大多数情况下,这种方法似乎是有效的,除了比特被反转。如果我查看fm中的输出文件,我希望看到以下内容:
File: header.out (0x0e bytes)
Byte: 0x0
00 00 96 cc 5f 00 00 00 34 c4 c4 93 4e f0 00 ..._...4...N...O
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
当事实上我看到这个:
File: header.out (0x0e bytes)
Byte: 0x0
00 00 f0 4e 93 c4 c4 34 00 00 00 5f cc 96 00 @O...N...4..._..
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
在创建比特集之前,我试图反转str,但这也没有产生所需的输出。
我想我对比特集的了解还不够,无法理解为什么会发生这种情况。非常感谢您的任何意见!此外,如果有不同的方法来实现这一点,请分享!
提前感谢。。。-J
直接将bitset<>
写入内存转储肯定是不可移植的,正如对reinterpret_cast<>
的需求所示。换句话说,即使数据被布置在一个漂亮的块中,你也不知道是如何做到的。
如果我是你,我会写一个更愚蠢的函数,从比特集中提取8比特的块,并使用普通访问运算符[]将它们作为字节写入文件。
至于另一种方法,当我想读/写二进制文件时,我通常会定义一个结构或一组直接映射到文件布局的结构。
例如:
struct Timestamp
{
int month:4;
int day:5;
int hour:5;
int minute:6;
int utcOffsetDirection:1;
int utcOffsetHour:5;
int utcOffsetMinute:5;
};
为什么不只使用结构位字段,只读取和写入结构,而不用担心进行"位解析"。只是要小心记忆对齐。确保添加一些填充以适合单词债券
struct timestamp{
unsigned mont:4;
unsigned day:5;
unsigned hour:5;
unsigned minute:6;
unsigned utc:1;
unsigned utc_hour:5;
unsigned utc_min:6
};
struct header{
int32_t file_length;
int32_t header_lenght;
int16_t version;
timestamp tmsp;
};
- 正在读取二进制文件(is_open)
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- Android 在编译二进制文件时重建静态库
- 在 C++ 中将双精度变量写入二进制文件
- clang 的 libFuzzer 可以在同一二进制文件中测试超过 1 个 API 吗?
- C++:实际上不是从二进制文件中读取
- 如何从二进制文件中的给定符号中获取调用程序图
- 将内部带有矢量的结构保存/读取到二进制文件中
- 编译多个C++文件.调用二进制文件以运行代码
- 如何使用位字段将数据从二进制文件复制到结构中?
- uint8_t同一二进制文件的不同十进制值
- C++单个生成文件多个二进制文件
- 尝试将数字写入二进制文件时引发异常
- C++中读/写二进制文件
- 如何忽略某些二进制文件的执行?
- 对在不同二进制文件中创建的对象文件的依赖关系
- 我的 SDL2 程序需要哪些二进制文件,以便它在另一台未安装 SDL2 的计算机中工作