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

解決済みの質問

汎用のファイル読み取り関数について

ファイルデータを読み取る関数を作成しています.
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);
}

投稿日時 - 2006-03-06 14:51:01

QNo.2010611

困ってます

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

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の回答も多分同様のことを言いたかったんだと思います。

投稿日時 - 2006-03-06 16:30:50

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

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

回答(2)

ANo.1

vfscanfを使用する。

va_argマクロは、va_start直後にapが正しい位置になるようにする為だけに1度だけ使用する。

投稿日時 - 2006-03-06 15:42:01