KianTern
KianTern

Reputation: 21

Parsing binary files in C++

I'm trying to read a binary format using C++ For some reason I'm able to parse only the first variable. The header sequence is: [2 byte integer][1 byte integer][1byte integer]

#include <iostream>
#include <fstream>

using namespace std;

struct HDR {
unsigned short int signature;
unsigned char version;
unsigned char tricnt;
} header;

int main(){
    ifstream infile("1.mdl",ios::in | ios::binary);
    if(!infile){
        cout<<"Error\n";
        return 1;
    }
    infile.read(reinterpret_cast<char *>(&header),sizeof(HDR));
    cout<<"SIG "<<header.signature<<endl;
    cout<<"VER "<<header.version<<endl;

    cout<<"TRI "<<header.tricnt<<endl;
    return 0;
}

For some reason I'm able to parse only the signature, the rest of the structure is empty.

Upvotes: 2

Views: 2980

Answers (1)

CB Bailey
CB Bailey

Reputation: 791341

Unless you have specific knowledge of the padding used by your implementation you should read into the members individually.

infile.read(reinterpret_cast<char *>(&header.signature), sizeof header.signature);
infile.read(reinterpret_cast<char *>(&header.version), sizeof header.version);
infile.read(reinterpret_cast<char *>(&header.tricnt), sizeof header.tricnt);

Of course, you are still relying on unsigned short being 2 bytes on your platform and the representation in the file having the same endianness as your machine but at least you aren't making assumptions about structure padding.

Naturally, when you're printing unsigned char the character represented will be printed. If you want to see the numeric value you should cast to a non-char integer type. ASCII 1 (start of header) and 3 (end of text) are control characters and not usually visible when printed.

cout<<"VER "<< static_cast<int>(header.version) <<endl;
cout<<"TRI "<< static_cast<int>(header.tricnt) <<endl;

Upvotes: 4

Related Questions