- ベストアンサー
汎用のファイル読み取り関数について
ファイルデータを読み取る関数を作成しています. Data *ReadFile (const char *name, Data *data, const char *format, ...) というプロトタイプを考えます. ここでDataはプログラマが自由に定義できる構造体です. この構造体の一例を示すと, typedef struct { int id; /* ID番号 */ char name[32]; /* 氏名 */ char sex; /* 性別 */ int age; /* 年齢 */ char addr[64]; /* 住所 */ } Data; という具合です. 読み取るファイルの書式はプログラムの種類によって 異なりますが, fopen関数やfclose関数を使用するといった 手順は全く同一です. そこで上記のような汎用的な ファイル読み取り関数を書こうと思ったのですが 読み取り部分fscanfの処理をどのように行えばよいか 分かりません. formatで指定する書式は'%'を区切りとする複数の文字列に 分け(例えばformat="%s %d"であればbuffer="%s \0%d\0"), char型のポインタ配列bpで参照できます. 可変引数の部分で 構造体のメンバを指定できるようにしたいのですが... ちなみに呼出側では Data *data; data = ReadFile ("a.txt", data, "%d %s %c %d %s", data->id, ...); というようにしたいと考えています. ソースを以下に示します. どなたかお力をお貸しくださいませ. Data *ReadFile (const char *name, Data *data, const char *format, ...){ FILE *stream; size_t data_size = 1024, buffer_size = 128, bp_size = 16; short i, j, k; char *buffer; char **bp; /* buffer pointer */ va_list ap; /* argument pointer */ (省略) va_start (ap, format); i = 0; k = 0; while (!feof (stream)) { fscanf (stream, bp[i], va_arg (ap, ????)); (省略) } va_end (ap); }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
fscanfの一般的な実装のソースを出しておきましょう。 この関数をベースにfopenやエラー処理なんかを付け加えればできると思う。 #include <stdio.h> #include <stdarg.h> int fscanf(FILE *fp, char const *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfscanf(fp, fmt, ap); va_end(ap); return (ret); } まあ通常fscanfはvfscanfに処理が丸投げされてるってことですね。ちなみにprintf系も同じです。 #1の回答も多分同様のことを言いたかったんだと思います。
その他の回答 (1)
- chie65536
- ベストアンサー率41% (2512/6032)
vfscanfを使用する。 va_argマクロは、va_start直後にapが正しい位置になるようにする為だけに1度だけ使用する。