C++读取二进制文件时的问题

问题描述 投票:0回答:1

这是生成二进制文件“输入”的代码:

#include <fstream>
int main() {
    unsigned char buf[] = {
        0x06, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00,
        0x6d, 0x0f, 0x00, 0x00, 0xc8, 0x42, 0x9a, 0x99, 0xd9, 0x3f, 0x62, 0x6f,
        0x79, 0x32, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x10, 0x00, 0x00, 0xa0, 0x42,
        0x9a, 0x99, 0xd9, 0x3f, 0x62, 0x6f, 0x79, 0x33, 0x00, 0x00, 0x00, 0x00,
        0x6d, 0x11, 0x00, 0x00, 0x70, 0x42, 0x9a, 0x99, 0xd9, 0x3f, 0x62, 0x6f,
        0x79, 0x34, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x12, 0x00, 0x00, 0x20, 0x42,
        0x9a, 0x99, 0xd9, 0x3f, 0x67, 0x69, 0x72, 0x6c, 0x31, 0x00, 0x00, 0x00,
        0x66, 0x13, 0x00, 0x00, 0x48, 0x42, 0x9a, 0x99, 0xd9, 0x3f, 0x67, 0x69,
        0x72, 0x6c, 0x32, 0x00, 0x00, 0x00, 0x66, 0x13, 0x00, 0x00, 0x48, 0x42,
        0x9a, 0x99, 0xd9, 0x3f};
    std::ofstream fout("input", std::ofstream::binary);
    fout.write((char *)buf, sizeof(buf));
    fout.close();
    return 0;
}

详细信息如下:第一个0x06表示有多少条记录,后面是一些记录,每条记录有姓名、性别('m'或'f')、年龄、体重和身高。

为了用 C++ 读取这个二进制文件,我创建了一个结构体:

struct Person{
    unsigned char name[8];
    unsigned char gender;
    unsigned int age;
    float weight,height;
}person[100];

下面的代码片段是我读取该文件的方式:

using namespace std;
ifstream fin;
fin.open("input",ios::binary);

int n;
fin.read(reinterpret_cast<char*>(&n),sizeof(n));

for(int i=0;i<n;i++)
     fin.read(reinterpret_cast<char*>(&person[i]),sizeof(person[i]));

我尝试进行输出,但随后出现乱码:

code:
for(int i=0;i<n;i++)
     cout<<person[i].name<<' '<<person[i].gender<<' '<<person[i].age<<' '<<person[i].weight<<' '<<person[i].height<<endl;

output:
boy1  2577023688 7.00208e+28 1.81062e-41
 � 863596386 0 6.25119e-42
pB���?boy4  309133312 40 1.7
girl1  2577023560 1.74727e+25 4.63068e-39
 � 0 0 0
  0 0 0

这让我很困惑。有人可以解释为什么会发生这种情况以及如何解决吗?

c++11 binaryfiles ifstream
1个回答
0
投票

你有几个问题。

第一,名字是8个字符,而不是10个。第二,年龄只有一个字节,而不是4个字节。 第三,因为您有混合类型,所以您会在结构中进行填充,从而使事情变得混乱。 您需要将其声明为“已打包”:

#include <iostream>
#include <fstream>
using namespace std;

struct Person{
    char name[8];
    char gender;
    unsigned char age;
    float weight,height;
} __attribute__((packed)) person[100];

int main()
{
    ifstream fin;
    fin.open("input",ios::binary);

    int n;
    fin.read(reinterpret_cast<char*>(&n),sizeof(n));
    cout << "Reading " << n << " records\n";
    cout << "Each is " << sizeof(Person) << " bytes\n";

    for(int i=0;i<n;i++)
        fin.read(reinterpret_cast<char*>(&person[i]),sizeof(person[i]));

    for(int i=0;i<n;i++)
        cout<<person[i].name<<" "<<person[i].gender<<" "<<(int)person[i].age<<" "<<person[i].weight<<" "<<person[i].height<<endl;
}

输出

Reading 6 records
Each is 18 bytes
boy1 m 15 100 1.7
boy2 m 16 80 1.7
boy3 m 17 60 1.7
boy4 m 18 40 1.7
girl1 f 19 50 1.7
girl2 f 19 50 1.7
© www.soinside.com 2019 - 2024. All rights reserved.