在c ++中读取字节

时间:2012-10-13 19:43:04

标签: c++ c++11 binary byte

我正在尝试从二进制文件中读取字节但没有成功。 我尝试了很多解决方案,但是没有得到结果。 文件结构:

[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);

4 个答案:

答案 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在系统上显示为B0B1B2B3B3B2B1B0并不重要,因为转换是通过位移处理的。代码不假设内存中有任何特定顺序。

答案 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()

相关问题