0

Here is a code to generate a binary file "input" :

#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;
}

The details are as : The first 0x06 indicates how many records are there, and the follows are some records, each with name, gender('m' or 'f'), age, weight and height.

To read this binary file in c++, I created a struct :

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

And the code fragment below is how I read this file :

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

and I try to make an ouput, but then it appears garbled codes :

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

and this makes me really comfused. Can someone explain why this will happen and how to solve it?

1
  • Your description is not correct. The name is only 8 bytes, not 10. Commented Nov 18 at 2:25

1 Answer 1

0

You have several problems.

First, the name is 8 characters, not 10. Second, the age is only one byte, not 4 bytes. Third, because you have mixed types, you are getting padding within the structure that messes things up. You need to declare it as "packed":

#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;
}

Output

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

In Windows, you'd use #pragma packed(1) instead of the attribute.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.