構造体をバイナリ形式で読み込むには?

解決


kmhp  2004-07-16 07:31:25  No: 54008

ある構造体(608byte)をバイナリ形式(fopen("...","rb")⇒fread(...))で一括読み込みしようとしているのですが、最初のパラメータ以降正確に読み取ってくれません。しかし同じソースコードをBC++でコンパイルするとうまくいったりします。なんとかVCで読み込みたいのですが、なにかVC特有の制約などがあるのでしょうか?何が原因で読み込めないのか、ご助言お願いいたします。


シャノン  2004-07-16 07:51:24  No: 54009

パディングとか?
まさか構造体にクラスとかポインタは持ってないですよね?


kmhp  2004-07-16 08:13:19  No: 54010

>>まさか構造体にクラスとかポインタは持ってないですよね?
一応、文字列とdouble型の配列があります。
さらに、小さな構造体も入ってます。

初めの書きこみの補足ですが、コンパイラはVC++6.0を使用してます。

ちなみに、パディングって何のことでしょうか?


瀬戸っぷ  2004-07-16 08:48:57  No: 54011

> ちなみに、パディングって何のことでしょうか?

せっかくネットが使えるのですから、「構造体 パディング」でgoogle検索してみましょう。
http://www.google.co.jp/search?q=%E6%A7%8B%E9%80%A0%E4%BD%93+%E3%83%91%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0&ie=UTF-8&hl=ja&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=lang_ja


シャノン  2004-07-16 09:42:48  No: 54012

構造体の中に
char str[ n ];
のように、文字列の実体があるのなら問題はありませんが、
char *pstr;
とかあるとダメです。
このポインタの値をファイルに書き込んで、次回ファイルからその値を復元しても、それが指し示す先に文字列の実体はありません。

パディングについては↑で。


kmhp  2004-07-16 23:32:14  No: 54013

↑パディングに関してはうかつな質問をしてしまい、すみませんでした。

さっそくsizeof()をもちいてBC++とVC++で比較しましたところ、
VC++における構造体のバイトが手計算の理論値より大きくなっていました(BC++はぴったりでした)。はじめのジャノンさんのご指摘とおり、パディングの可能性大です。

パディングの挿入はコンパイラに依存するらしいのですが、
VC++においてパディングを入らないようにする、
あるいは回避するためにはどうしたらよいのでしょうか?
改めてお願いします。


瀬戸っぷ  2004-07-16 23:48:34  No: 54014

> VC++においてパディングを入らないようにする、
> あるいは回避するためにはどうしたらよいのでしょうか?

[プロジェクト][設定]でプロジェクトの設定ダイアログを表示して、C/C++タブを選択。
[カテゴリ]を「コード生成」にすると、「構造体メンバのアライメント」というのがありますので、
1バイトに設定すればパディングはなくなると思います。

# 試したコトはないですけどね。


シャノン  2004-07-17 01:38:00  No: 54015

VC++ であれば、

#pragma pack(1)
// ここで構造体宣言
#pragma pack()

と書くことでもパディングをつぶせます。
また、やってることは同じなのですが、Win32 API のヘッダファイルなどでは

#include <pshpack1.h>
// 構造体宣言
#include <poppack.h>

とやっているようです。


kmhp  2004-07-17 05:00:45  No: 54016

シャノンさん、瀬戸っぷさん、ありがとうございました。
お二人の指摘された方法で試したところ、ともにうまく読みこむ事ができました。

実は今までこの疑問をうやむやにしており、直接ファイルポインタを動かして構造体の情報を取得するという荒業をしておりました(←コードが汚なくなって本当にいやだった)。
したがって今回、この疑問が解決したことはうれしい限りです。

本当にありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加