- ベストアンサー
fwriteでの書き込み
16進の数値をバイナリとしてファイルに書き込みたいのですが、 以下のようなプログラムで書き込んで、できたファイルを16進に 直して見てみると、 ff ff 00 00 aa ff 00 00 となっていて、途中に0000が入ってしまうのです。 16進に直して見たときに ff ff aa ff cc 55 22 22 となるようにしたいのですが、どこがまちがっているのでしょうか? int main(void){ long *i; FILE *fp1; fp1=fopen("test.dat","w"); i[0]=0xffff; i[1]=0xffaa; i[2]=0x55cc; i[3]=0x2222; fwrite(i,2,4,fp1)); fclose(fp1); return 0; }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#2の方、おしい... エンディアン(endian)はマシン(プロセッサ)アーキテクチャに依存します。 オペレーティングシステムに依存するわけではありません。 Windowsが動くマシンがIntelのPentiumというプロセッサで、x86と呼ばれるアーキテクチャがリトルエンディアンを採用しているからです。 質問者の方は、リトルエンディアンとかビッグエンディアンとかいうのはご存知ですかね? でも、質問内容では気になさってないようですね。(自然とリトルエンディアンであることを受け入れていらっしゃる...) では、質問の直接の回答を... 4バイトの型であるlongをご使用になっているのを、2バイトの型であるshortにします。 でも...このプログラムどうして動くのか不思議ですよ。 データを格納する配列 i[]は定義されていない、定義されているのはポインタの i ですから。(ポインタで定義されているiに対して、i[n]という使い方が誤っているというつもりではありません。Cの言語仕様はそれを認めています。) 動いているとすれば、自動変数であるポインタ i の初期化がされていないので、きっと不定のメモリに、0x0000ffffなどを書き込んで、しかも、ランタイムエラーとならない...ただの偶然ですよ。 ということで、目的とすることをなさるには、 unsigned short i[4]; <途中省略> fwrite(&i[0], 2, 4, fp1); とするのが正解です。 参考になれば。
その他の回答 (2)
- honiyon
- ベストアンサー率37% (331/872)
こんちには、honiyonです。 以下の2点がミソです。 ・long型は 4byte ・Windowsはスモールインディアン Windowsはスモールインディアンなので、ファイルにデータを書き込むと上位ビットと下位ビットが逆になって保存されます。(スモールインディアンの詳細が知りたい場合は別途調べてみてください。) つまり、0xffffというデータは、long型では、0000 ffff (4byte)と表せます。これをファイルに保存すると、上位ビットと下位ビットが逆転し、ffff 0000 というデータが保存されます。 もし、ffffだけ保存したいなら、2byteのデータ型を使うと良いと思います。 確かsmallint型が2byteだったような・・・ってsmallintってDelphiの型だったかな?(汗 ここは自身無しでお願いします(^^; 参考になれば幸いです(..
お礼
endianの言葉を始めて知りました。 新しい知識が増えました! ありがとうございました。
> 16進の数値をバイナリとしてファイルに書き込みたいのですが、 > 以下のようなプログラムで書き込んで、できたファイルを16進に > 直して見てみると、 > > ff ff 00 00 aa ff 00 00 > > となっていて、途中に0000が入ってしまうのです。 > 16進に直して見たときに > > ff ff aa ff cc 55 22 22 > > となるようにしたいのですが、どこがまちがっているのでしょうか? 逆質問です。 (1) ご使用の開発環境(コンパイラ)は何でしょうか? (2) ご使用の環境でsizeof(long)はいくつになりますか? (3) エンディアンの違いは考慮しなくてもよいのですか? # C言語はよく知らないので、他の方のフォローを希望 (^人^;;
お礼
shortにするといいということですね!
お礼
ありがとうございました。