こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

構造体の文字列データをファイルへ書き込む方法は?

構造体の文字列データをファイルへ書き込む方法として、構造体のデータを一気に書き込まずに、データ毎に書き込むことを勉強としてやってみようとしました。

数字の場合はうまくいったのですが、文字列の場合が分かりません。

ご存知の方、よろしくお願いいたします。

<数字の場合>
typedef struct {
int m1, m2;
} Data;

fwrite(&data[i].m1, sizeof(int), 1, fp);
fwrite(&data[i].m2, sizeof(int), 1, fp);

<文字列の場合>
#include <stdio.h>

typedef struct {
char m1[10], m2[10];
} Data;

int main()
{
static Data data[3] = {
{ "a1", "b1"},
{ "c1", "d1"},
{ "e1", "f1"},
};

Data data2[10];
FILE *fp;
int i, n;

fp = fopen("file.dat", "wb");
if (fp == NULL) return 1;
for (i = 0; i < 3; i++) {
fwrite(&data[i].m1, sizeof(Data.m1[10]), 1, fp); ← sizeofでエラーが出る
fwrite(&data[i].m2, sizeof(Data.m2[10]), 1, fp);

}
fclose(fp);

以下省略

投稿日時 - 2003-05-01 09:22:02

QNo.536426

暇なときに回答ください

質問者が選んだベストアンサー

まずコンパイルエラーですが、sizeofで指定するのは型か変数です。
Data.m1[10]
ではそのどちらにも該当せずにエラーになります。
data[i].m1[10]
という書き方ならOKでしょう。

しかしこれでは期待通りの動作にはならないですね。
sizeofは 変数そのものがどれだけ領域を使っているかを返してくれるものですから、この書き方ですと data[i].m1[10] は char のサイズ、つまり 1 を返します。

m1 の 10 という値を返して欲しければ sizeof(data[i].m1) とすれば 10が返ります。
文字列の長さを返して欲しいのなら sizeofは使えません。自分で文字の数を数えるか strlenという関数を使います。

例えば strlen(data[0].m1) とすれば 2が返ります。このとき NULL までファイルに書き込みたいのなら +1した値を fwriteに渡さなければなりません。

ファイルに文字列を書き出したいのなら fprintf という関数もあります。

投稿日時 - 2003-05-01 10:36:32

お礼

回答ありがとうございました。

投稿日時 - 2003-05-01 11:56:34

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

>sizeof(data[0].m1)とsizeof(data[i].m1)のどちらが正攻法なのでしょうか?

どちらが正攻法なのかは自信がありません。ただ、どちらも同じコードが生成されるとは思います(たぶん)。

>→変数が2つあるのでsizeof(char[20])が正解でしょうか?

この例ではそれでも動作すると思います(これもたぶん)。ただ、一般的には好ましくありません。構造体の定義で隣あっているメンバであっても、メモリ上で並んでいる保証はありません。数バイト程度の空きがある可能性があります。

投稿日時 - 2003-05-01 15:38:24

お礼

回答ありがとうございました

投稿日時 - 2003-05-01 23:35:43

ANo.2

fwriteの第2引数が何を意味するかわかっていますか?
# わからないなら調べましょう

投稿日時 - 2003-05-01 10:31:50

お礼

回答ありがとうございました。

投稿日時 - 2003-05-01 11:56:07

ANo.1

for (i = 0; i < 3; i++) {
fwrite(data[i].m1, sizeof(data[0].m1), 1, fp);
fwrite(data[i].m2, sizeof(data[0].m2), 1, fp);
}

とすればできます。この場合、第1パラメータの&はあってもなくても構いません。(あくまでこの例の場合) また、sizeofのオペランド(演算対象)を変数でなく型にしたい場合、sizeof(char[10])としても同様の結果が得られます。

投稿日時 - 2003-05-01 10:30:15

補足

sizeof(data[0].m1)とsizeof(data[i].m1)のどちらが正攻法なのでしょうか?


>変数でなく型にしたい場合、sizeof(char[10])としても同様の結果が得られます。
→変数が2つあるのでsizeof(char[20])が正解でしょうか?

投稿日時 - 2003-05-01 11:53:00

お礼

回答ありがとうございました

投稿日時 - 2003-05-01 11:52:45