我正在尝试从二进制文件中读取字节但没有成功。 我尝试了很多解决方案,但是没有得到结果。 文件结构:
[offset] [type] [value] [description]
0000 32 bit integer 0x00000803(2051) magic number
0004 32 bit integer 60000 number of images
0008 32 bit integer 28 number of rows
0012 32 bit integer 28 number of columns
0016 unsigned byte ?? pixel
0017 unsigned byte ?? pixel
........
xxxx unsigned byte ?? pixel
我是如何尝试的(不起作用):
auto myfile = fopen("t10k-images.idx3-ubyte", "r");
char buf[30];
auto x = fread(buf, 1, sizeof(int), myfile);
答案 0 :(得分:3)
将字节读为unsigned char
:
ifstream if;
if.open("filename", ios::binary);
if (if.fail())
{
//error
}
vector<unsigned char> bytes;
while (!if.eof())
{
unsigned char byte;
if >> byte;
if (if.fail())
{
//error
break;
}
bytes.push_back(byte);
}
if.close();
然后将多个字节转换为32-bit integer
,例如:
uint32_t number;
number = ((static_cast<uint32_t>(byte3) << 24)
| (static_cast<uint32_t>(byte2) << 16)
| (static_cast<uint32_t>(byte1) << 8)
| (static_cast<uint32_t>(byte0)));
这应涵盖端序问题。如果int
在系统上显示为B0B1B2B3
或B3B2B1B0
并不重要,因为转换是通过位移处理的。代码不假设内存中有任何特定顺序。
答案 1 :(得分:2)
这是您从文件中读取uint32_t的方式:
auto f = fopen("", "rb"); // not the b, for binary files you need to specify 'b'
std::uint32_t magic = 0;
fread (&magic, sizeof(std::uint32_t), 1, f);
希望这有帮助。
答案 2 :(得分:1)
了解文件布局的字节顺序,读取多字节数字非常重要。假设big-endian 总是写入格式,并假设该值确实是32位无符号值:
uint32_t magic = 0;
unsigned char[4] bytes;
if (1 == fread(bytes, sizeof(bytes), 1, f))
{
magic = (uint32_t)((bytes[0] << 24) |
(bytes[1] << 16) |
(bytes[2] << 8) |
bytes[3]);
}
注意:无论 reader (您的程序)是小端还是大端,这都会有效。我敢肯定我至少错过了一次演员阵容,但希望你能明白这一点。读取多字节数字的唯一安全和便携式方法是(a)知道它们被写入的字节顺序,以及(b)读取和组装它们逐字节。
答案 3 :(得分:1)
C ++流库函数read()
可用于二进制文件I / O.鉴于链接中的代码示例,我将从这样开始:
std::ifstream myfile("t10k-images.idx3-ubyte", std::ios::binary);
std::uint32_t magic, numim, numro, numco;
myfile.read(reinterpret_cast<char*>(&magic), 4);
myfile.read(reinterpret_cast<char*>(&numim), 4);
myfile.read(reinterpret_cast<char*>(&numro), 4);
myfile.read(reinterpret_cast<char*>(&numco), 4);
// Changing byte order if necessary
//endswap(&magic);
//endswap(&numim);
//endswap(&numro);
//endswap(&numco);
if (myfile) {
std::cout << "Magic = " << magic << std::endl
<< "Images = " << numim << std::endl
<< "Rows = " << numro << std::endl
<< "Cols = " << numco << std::endl;
}
如果字节顺序(Endianness)应该反转,你可以编写一个简单的反向函数,如下所示:endswap()