-2

私のプログラムでは、キーボードから入力を受け取ります。その入力を、 2 つのフィールドと 1structつのフィールドを含むに入れました。関数のみを使用して全体に書き込むにはどうすればよいですか?charintstruct

の各メンバーに個別に書き込みたくありません。struct

4

2 に答える 2

4

Cには「命令」がありません。

次のような単一の関数呼び出しを使用できるはずです。

fwrite(&mystructure, sizeof mystructure, 1, myfile);

しかし、これには欠点がないわけではありません。

  1. これにより、ファイル形式が現在の CPU とコンパイラに依存するようになります。これは多くの場合、悪い考えです。相互運用性を維持することが非常に難しくなります。
  2. 書き込みは部分的に成功する可能性があります。その場合はループでラップする必要があります。
于 2013-03-20T11:38:55.357 に答える
1

これは、 yourstructがどのように定義されているか、出力を人間が読めるようにするかどうか、および出力ファイルが別のアーキテクチャで読み取られることを意図しているかどうかによって異なります。

fwrite他の人が与えた解決策は、構造体のバイナリ表現を出力ファイルに書き込みます。たとえば、次のコードがあるとします。

#include <stdio.h>

int main(void)
{
  struct foo {
    int x;
    char name1[10];
    char name2[10];
  } items[] = {{1,"one","ONE"}, {2,"two","TWO"}};

  FILE *output = fopen("binio.dat", "w");

  fwrite( items, sizeof items, 1, output );

  fclose( output );
  return 0;
}

の内容をbinio.datコンソールに表示すると、次のようになります。

john@marvin:~/Development/Prototypes/C/binio$ cat binio.dat
oneONEtwoTWOjohn@marvin:~/開発/プロトタイプ/C/binio$

john@marvin:~/Development/Prototypes/C/binio$ od -c binio.dat
0000000 001 \0 \0 \0 1 \0 \0 \0 \0 \0 \0 \0 ON
0000020 E \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000040 \0 \0 \0 \0 002 \0 \0 \0 2 \0 \0 \0 \0 \0
0000060 \0 \0 2 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000100 \0 \0 \0 \0 \0 \0 \0 \0
0000110

整数値は、印刷可能な文字ではないバイト シーケンス 01, 00, 00, 00 および 02, 00, 00, 00 (x86 はリトル エンディアン) として格納されているため、ガベージ (上記では再現されていません) として表示されます。 . また、 の 10 文字name1すべてと の 20 文字すべてname2がファイルに書き込まれることに注意してください。これは、必要な場合とそうでない場合があります。

構造体にポインターが含まれている場合、状況はさらに複雑になります。ファイルに格納されるのはポインター値であり、ポイントされているものではないためです。

#include <stdio.h>

int main(void)
{
  struct foo {
    int x;
    char *name1;
    char *name2;
  } items[] = {{1,"one","ONE"}, {2,"two","TWO"}};

  FILE *output = fopen("binio.dat", "w");

  fwrite( items, sizeof items, 1, output );

  fclose( output );
  return 0;
}

今回私は得る

john@marvin:~/Development/Prototypes/C/binio$ cat binio.dat
��������john@marvin:~/開発/プロトタイプ/C/binio$

john@marvin:~/Development/Prototypes/C/binio$ od -c binio.dat
0000000 001 \0 \0 \0 260 205 004 \b 264 205 004 \b 002 \0 \0 \0
0000020 270 205 004 \b 274 205 004 \b
0000030

ファイルには文字列がまったく表示されないことに注意してください。このファイルを別のプログラムで読み込むと、(ほとんどの場合) 無効なアドレスしか表示されません。

出力を人間が判読できるようにし、それらの値を別のアーキテクチャで読み取れるようにたい場合は、ほとんどフォーマットされた出力を使用する必要があります。つまり、各メンバーを個別に記述する必要があります。

#include <stdio.h>

int main(void)
{
  struct foo {
    int x;
    char *name1;
    char *name2;
  } items[] = {{1,"one","ONE"}, {2,"two","TWO"}};

  FILE *output = fopen("binio.dat", "w");
  int i;
  for (i = 0; i < sizeof items / sizeof items[0]; i++)
  {
    fprintf(output, "%d %s %s\n", items[i].x, items[i].name1, items[i].name2);
  }
  fclose( output );
  return 0;
}
john@marvin:~/Development/Prototypes/C/binio$ cat binio.dat
1つ1つ
2 2 2

あなたは確かにその操作をあなた自身の関数でラップすることができます。

int printFoo( FILE *output, const struct foo item )
{
  return fprintf( output, "%d %s %s\n", item.x, item.name1, item.name2);
}

しかし、結局のところ、それは可能な限り単純です。

可読性と移植性を気にしない場合、このfwriteソリューションはうまく機能しますが、構造体内にポインター メンバーがある場合は注意が必要です。

于 2013-03-20T12:23:24.550 に答える