2

これを複数の場所で調べようとしましたが、fwrite が機能しない理由がわかりません。

100 個のフィールドを持つ構造体がある場合、100 個の書式指定子で fprintf を使用したくありません。

struct emp
{
      char name[15];
      int age;
      int salary;
      char address[30];
};


int main()
{

    char str[60];
    struct emp emp1[5] = {{"Yoda",23,45000,"Asia"},{"Darth",34,2344,"NAmerica"},{"Jabba",22,5566,"Africa"},{"Luke",33,3399,"SAmerica"},{"Laya",44,6677,"Europe"}};

    FILE *fp;
    fp = fopen("C:/.../sampleText.txt","w");`
    int i=0;
   for(i=0; i<5; i++)
   {

            fwrite(&emp1[i],sizeof(emp1[i]),1,fp);

           //fprintf(fp,"%s, %d, %d, %s\n",&emp1[i].name,emp1[i].age,emp1[i].salary,emp1[i].address);
    }

    fclose(fp);
    getch();
 }
4

4 に答える 4

3

2 つの答えがあります。

  1. すべてが正しく設定されていて、書き込まれたデータを他のマシンに移植することが問題にならない場合は、機能します。
  2. データ構造に多数の一般的な機能がある場合、またはあるタイプのマシン (Intel マシンなど) から別のタイプ (PowerPC や SPARC など) にデータを移動する必要がある場合は機能しません。

あなたの例の構造にはポインタがないので、構造をそのままファイルに書き込んでから、同じ(タイプの)マシンで実行されているプログラムの別の呼び出しで、それを読み戻すことができます。同じデータ。

ただし、構造体にポインタが含まれていると、構造体を意味のある形でディスクに書き込むことができませんでした。プログラムの 1 つの呼び出しでのポインターは、プログラムの別の呼び出しで意味を持つ必要はありません。リトル エンディアン (Intel) マシンとビッグ エンディアン (PowerPC、SPARC) マシンの間でデータを移植する必要がある場合は、プラットフォームに依存しない方法でデータにアクセスする必要があります。データをディスクに書き込むだけでは機能しません。


したがって、移植性が問題にならない場合、このコードは動作するはずです (Unix または Windows)。データはプレーン テキストではなくバイナリ データであるため、"wb"との"rb"引数を使用します。fopen()bオプションですが、Unix では無害です。これは、Windows では非常に重要です。また、コードはファイル名を に修正してsampledata.bin、現在のディレクトリに書き込んで、どちらのプラットフォームでも実行できるようにします。データを書き込みます。次に、データを読み取ります。次に、読み取ったデータと書き込まれたデータを比較し、問題があれば報告します。プログラムが何も言わなければ、すべて問題ありません。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct emp
{
    char name[15];
    int age;
    int salary;
    char address[30];
};

int main(void)
{
    char const filename[] = "sampledata.bin";
    struct emp emp1[5] =
    {
        { "Yoda",  23, 45000, "Asia"      },
        { "Darth", 34,  2344, "N America" },
        { "Jabba", 22,  5566, "Africa"    },
        { "Luke",  33,  3399, "S America" },
        { "Leia",  44,  6677, "Europe"    },
    };
    struct emp emp2[5];
    FILE *ifp;
    FILE *ofp;
    int i;

    ofp = fopen(filename, "wb");
    if (ofp != 0)
    {
        if (fwrite(emp1, sizeof(emp1), 1, ofp) != 1)
        {
            fprintf(stderr, "Failed to write to %s\n", filename);
            exit(1);
        }
        fclose(ofp);
    }

    ifp = fopen(filename, "rb");
    if (ifp != 0)
    {
        if (fread(emp2, sizeof(emp2), 1, ifp) != 1)
        {
            fprintf(stderr, "Failed to read from %s\n", filename);
            exit(1);
        }
        fclose(ifp);
    }

    for (i = 0; i < 5; i++)
    {
        if (emp1[i].age != emp2[i].age ||
            emp1[i].salary != emp2[i].salary ||
            strcmp(emp1[i].name, emp2[i].name) != 0 ||
            strcmp(emp1[i].address, emp2[i].address) != 0)
            printf("Difference in record %d\n", i);
    }

    return 0;
}

ファイルの内容sampledata.bin:

0x0000: 59 6F 64 61 00 00 00 00 00 00 00 00 00 00 00 00   Yoda............
0x0010: 17 00 00 00 C8 AF 00 00 41 73 69 61 00 00 00 00   ........Asia....
0x0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x0030: 00 00 00 00 00 00 00 00 44 61 72 74 68 00 00 00   ........Darth...
0x0040: 00 00 00 00 00 00 00 00 22 00 00 00 28 09 00 00   ........"...(...
0x0050: 4E 20 41 6D 65 72 69 63 61 00 00 00 00 00 00 00   N America.......
0x0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x0070: 4A 61 62 62 61 00 00 00 00 00 00 00 00 00 00 00   Jabba...........
0x0080: 16 00 00 00 BE 15 00 00 41 66 72 69 63 61 00 00   ........Africa..
0x0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x00A0: 00 00 00 00 00 00 00 00 4C 75 6B 65 00 00 00 00   ........Luke....
0x00B0: 00 00 00 00 00 00 00 00 21 00 00 00 47 0D 00 00   ........!...G...
0x00C0: 53 20 41 6D 65 72 69 63 61 00 00 00 00 00 00 00   S America.......
0x00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x00E0: 4C 65 69 61 00 00 00 00 00 00 00 00 00 00 00 00   Leia............
0x00F0: 2C 00 00 00 15 1A 00 00 45 75 72 6F 70 65 00 00   ,.......Europe..
0x0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x0110: 00 00 00 00 00 00 00 00                           ........
0x0118:
于 2013-11-09T06:21:40.977 に答える
2

の意味を指定していませんfwrite doesn't workが、Windows で作業していると仮定します。その場合は to を指定する必要があり"wb"ますfopen。Windows のデフォルトでは、書き込み中ですtext mode(つまり"wt")。

于 2013-11-09T06:44:55.753 に答える
1

structファイルやソケットにそのまま書き込むのは得策ではありません。問題解決にコンプレックスを招きます。最善の方法は、書き込みの前にシリアル化を使用することです。また、ジムが上で指摘したように、必ずファイルをバイナリで開いてください。

この質問と回答を見てください。あなたの質問に対するかなり良い答えと説明があります。 Cのソケットを介して構造体を渡す

于 2013-11-09T07:11:10.310 に答える