ある構造体(608byte)をバイナリ形式(fopen("...","rb")⇒fread(...))で一括読み込みしようとしているのですが、最初のパラメータ以降正確に読み取ってくれません。しかし同じソースコードをBC++でコンパイルするとうまくいったりします。なんとかVCで読み込みたいのですが、なにかVC特有の制約などがあるのでしょうか?何が原因で読み込めないのか、ご助言お願いいたします。
パディングとか?
まさか構造体にクラスとかポインタは持ってないですよね?
>>まさか構造体にクラスとかポインタは持ってないですよね?
一応、文字列とdouble型の配列があります。
さらに、小さな構造体も入ってます。
初めの書きこみの補足ですが、コンパイラはVC++6.0を使用してます。
ちなみに、パディングって何のことでしょうか?
> ちなみに、パディングって何のことでしょうか?
せっかくネットが使えるのですから、「構造体 パディング」で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
構造体の中に
char str[ n ];
のように、文字列の実体があるのなら問題はありませんが、
char *pstr;
とかあるとダメです。
このポインタの値をファイルに書き込んで、次回ファイルからその値を復元しても、それが指し示す先に文字列の実体はありません。
パディングについては↑で。
↑パディングに関してはうかつな質問をしてしまい、すみませんでした。
さっそくsizeof()をもちいてBC++とVC++で比較しましたところ、
VC++における構造体のバイトが手計算の理論値より大きくなっていました(BC++はぴったりでした)。はじめのジャノンさんのご指摘とおり、パディングの可能性大です。
パディングの挿入はコンパイラに依存するらしいのですが、
VC++においてパディングを入らないようにする、
あるいは回避するためにはどうしたらよいのでしょうか?
改めてお願いします。
> VC++においてパディングを入らないようにする、
> あるいは回避するためにはどうしたらよいのでしょうか?
[プロジェクト][設定]でプロジェクトの設定ダイアログを表示して、C/C++タブを選択。
[カテゴリ]を「コード生成」にすると、「構造体メンバのアライメント」というのがありますので、
1バイトに設定すればパディングはなくなると思います。
# 試したコトはないですけどね。
VC++ であれば、
#pragma pack(1)
// ここで構造体宣言
#pragma pack()
と書くことでもパディングをつぶせます。
また、やってることは同じなのですが、Win32 API のヘッダファイルなどでは
#include <pshpack1.h>
// 構造体宣言
#include <poppack.h>
とやっているようです。
シャノンさん、瀬戸っぷさん、ありがとうございました。
お二人の指摘された方法で試したところ、ともにうまく読みこむ事ができました。
実は今までこの疑問をうやむやにしており、直接ファイルポインタを動かして構造体の情報を取得するという荒業をしておりました(←コードが汚なくなって本当にいやだった)。
したがって今回、この疑問が解決したことはうれしい限りです。
本当にありがとうございました。
ツイート | ![]() |