-1

私はここで新しく、構造体があるという質問があります。たとえば、全体のサイズが8バイトであるとしましょう。ここでは、構造体です。

struct Header 
{
    int ID;             // 4 bytes
    char Title [4];     // 4 bytes too
}; // so it 8 bytes right?

そして私も8バイトのファイルを持っています...私はただ尋ねたいのですが、そのファイルのデータをその構造体に解析する方法

私はこれを試しました:

    Header* ParseHeader(char* filename)
    {
        char* buffer = new char[8];
        fstream fs(filename);

        if (fs.is_open() != true)
            throw new exception("Couldn't Open file for Parsing Header.");

        fs.read(buffer, 8);

        if (!fs)
        {
            delete[] buffer;
            throw new exception("Couldn't Read header OJN file.\nHeader data was corrupted");
        }

        Header* header = (Header*)((void*)buffer);
        delete[] buffer;
        fs.close();

        return header;
    }

しかし、失敗し、予想よりも無効なデータが返されます(これはファイルの障害ではなく、ファイルが正しく構造化されていることを確認できます)

誰かが私を助けることができますか?ありがとう

4

4 に答える 4

1

この時点まではすべてうまくやっているようです。

Header* header = (Header*)((void*)buffer);
delete[] buffer;
fs.close();

キャスト後にバッファを削除することに注意してください。つまり、ヘッダーは削除された場所->ジャンクを指しています。引き続きデータを使用する場合は、データを削除またはコピーしないでください。

また、正直なところ、コードがどのようにコンパイルされるかはわかりません。関数は、ヘッダーを返すのに対し、ヘッダーを返すと述べています*。

于 2013-03-26T07:15:46.793 に答える
0

You are deleting the data that is being returned. Therefore header is no longer accessible.

I think you meant the line to be:

Header header = *(Header*)((void*)buffer);

This will actually copy the header.

于 2013-03-26T07:15:48.690 に答える
0

The fact that your 8 bytes file correctly maps to your struct Header is mere luck as far as C++ is involved. The structure could have internal padding that make it bigger than 8 bytes, and the data endianness could be different between your file and your CPU.

I realize your code works with your particular compiler version, on your operating system and on your CPU but you should not get into the habit of coding like that, otherwise you'll probably get into big trouble as soon as you change any of those parameters (or maybe even just some compiler flags). In other words, what you are doing is extremely bad practice. In C++ you don't even have the guarantee that an int is actually 4 bytes.

The Right Way™ to load such binary data from a file is to load each field individually and ensure proper endianness conversion depending on the CPU you're using (eg. through hton* / ntoh* or similar functions). Using a fixed-size type like int32_t also helps.

于 2013-03-26T08:02:32.307 に答える
0

Just define your structure in 1-byte boundary as:

#pragma pack(1)
struct Header 
{
    int ID;             // 4 bytes
    char Title [4];     // 4 bytes too
};
#pragma pack()

First pack statement instructs the compiler to use one-byte padding for members in structure. This way size of Header will be 8 bytes. Second pack statement instructs to go back to default setting. You may need to use push and pop instructions (See enter link description here) - but this isn't required for you.

Secondly, and more importantly, you should not use hard-code values like 8. Always use sizeof to read or write a structure. Also, this statement is absolutely not needed:

char* buffer = new char[8];
...

Just declare Header variable itself, and read on it:

Header header;
...
fs.read(&header, sizeof(Header));
于 2013-03-27T06:14:48.693 に答える