3

C の I/O 関数を使用してバイナリ ファイルにデータを書き込む必要があります。次のコードにより、実行時例外が発生します。


#include "stdio.h"

int main(int argc,char* argv[]) {
    FILE *fp = fopen("path_to_file.bin","wb");
    if(fp == NULL) {
        printf("error creating file");
        return -1;
    }
    int val = 4;
    fwrite((const void*)val,sizeof(int),1,fp);
    fclose(fp);
    return 0;
}

コードは fwrite で死ぬ。私が間違っていることを見つけることができますか?どうやら、0x0000004 などのデータにアクセスしようとしているようです。

ありがとう !

4

6 に答える 6

25

ニールの答えは改善できると思います。私はそれがすでに受け入れられていることを認識しているので、これは単に対比を示すためのものです (これが、私が彼を編集しなかった理由です)。

fwrite(&val, sizeof val, 1, fp);

2 つの改善点:

  • C では必要なく、エラーを隠すことができるため、ポインターのキャストはありません。
  • ポインターを渡す対象であるため、オブジェクトで直接使用sizeofします。私には非常に理にかなっており、同じことを繰り返して型名を使用するよりも安全です。
于 2009-04-21T11:29:04.063 に答える
18
 fwrite((const void*)val,sizeof(int),1,fp);

次のようにする必要があります。

 fwrite((const void*) & val,sizeof(int),1,fp);

ところで、キャストを使用しないと、適切なエラー メッセージが表示されます。キャストは、C (および C++) プログラマーによって本来よりもはるかに頻繁に使用される傾向があります。経験則として、「キャストが必要な場合、それはおそらく間違っている」と言えます。

于 2009-04-21T11:22:12.330 に答える
5

ニールの答えに追加:これは、同じプラットフォームでファイルを読み書きしているときに機能します。エンディアンが異なるプラットフォーム間で読み取り/書き込みを行うと、事態が奇妙になる可能性があります。

于 2009-04-21T11:26:18.327 に答える
0

私もこのような問題に直面しました。これが私の解決策です。

fwrite(val, sizeof(val[0], sizeof(val)/sizeof(val[0]), fp);

于 2016-11-09T04:02:38.440 に答える
0
#include "stdio.h"

int main(int argc,char* argv[]) {
    FILE *fp = fopen("path_to_file.bin","wb");
    if(fp == NULL) {
        printf("error creating file");
        return -1;
    }
    int val = 4;
    fwrite((const void*)val,sizeof(int),1,fp);

整数そのものではなく、アドレスを指定する必要があります。

さらに、次のような方法で整数を使用しないでください。

  1. 異なるコンピューターではエンディアンが異なる場合があります(前述のとおり)
  2. サイズが異なる場合がございます。非常に古いコンピュータでは、1 バイトまたは 2 バイトになる場合があります。最新のほとんどでは 4 ですが、 8 になることもあります (一部の 64 ビット コンピュータ)。一部の奇妙なアーキテクチャでは、36 ビットでさえある場合があります。int32_t val = 4; fwrite((const void *)val, 4, 1, fp)問題を解決する必要があります。

ソフトウェアを移植する必要はないと思うかもしれません。多くの設計者 (ソフトウェアとハ​​ードウェア) が同様の仮定を立てました。作成しないのはコストがかかりすぎる場合もありますが、この場合は、いくつかの追加チェックの問題です。

    fclose(fp);
    return 0;
}
于 2009-04-21T18:14:37.707 に答える