Cでファイルポインタを「動的に」割り当てることは可能ですか?私が言いたいのはこれです:
FILE **fptr;
fptr = (FILE **)calloc(n, sizeof(FILE*));
ここで、nは整数値です。ポインタ値の配列が必要ですが、ユーザー入力を取得する前にいくつあるかわからないため、ハードコーディングできません。どんな助けでも素晴らしいでしょう!
Cでファイルポインタを「動的に」割り当てることは可能ですか?私が言いたいのはこれです:
FILE **fptr;
fptr = (FILE **)calloc(n, sizeof(FILE*));
ここで、nは整数値です。ポインタ値の配列が必要ですが、ユーザー入力を取得する前にいくつあるかわからないため、ハードコーディングできません。どんな助けでも素晴らしいでしょう!
フレキシブル配列(またはフレックス配列)と呼ばれることもあるもの、つまり、プログラムの存続期間中にサイズが動的に変化する配列を実装しようとしています。このようなエンティティは、Cのネイティブ型システムには存在しません。自分で実装する必要があります。以下では、これが配列内の要素のタイプであると想定します。これT
は、アイデアが特定のタイプのコンテンツとは何の関係もないためです。(あなたの場合、T
ですFILE *
。)
多かれ少なかれ、次のような構造体が必要です。
struct flexarray {
T *array;
int size;
}
この構造を初期化および操作するための関数ファミリー。まず、基本的なアクセサを見てみましょう。
T fa_get(struct flexarray *fa, int i) { return fa->array[i]; }
void fa_set(struct flexarray *fa, int i, T p) { fa->array[i] = p; }
int fa_size(struct flexarray *fa) { return fa->size; }
簡潔にするために、これらの関数はエラーチェックを行わないことに注意してください。実生活では、境界チェックをfa_get
とに追加する必要がありfa_set
ます。これらの関数は、flexarray
がすでに初期化されていることを前提としていますが、その方法は示していません。
void fa_init(struct flexarray *fa) {
fa->array = NULL;
fa->size = 0;
}
これにより、flexarrayが空として開始されることに注意してください。このような初期化子で固定の最小サイズの配列を作成するのが一般的ですが、サイズ0から開始すると、配列拡張コード(以下に表示)を実行でき、ほとんどの実際の状況ではほとんど費用がかかりません。
そして最後に、どうやってflexarray
大きくするのですか?それは実際には非常に簡単です:
void fa_grow(struct flexarray *fa) {
int newsize = (fa->size + 1) * 2;
T *newarray = malloc(newsize * sizeof(T));
if (!newarray) {
// handle error
return;
}
memcpy(newaray, fa->array, fa->size * sizeof(T));
free(fa->array);
fa->array = newarray;
fa->size = newsize;
}
flexarrayの新しい要素は初期化されていないため、フェッチする前に、新しい各インデックスiに何かを格納するように調整する必要があることに注意してください。
毎回一定の乗数でフレックスアレイを成長させることは、一般的に良い考えです。代わりに、サイズを一定の増分で増やすと、配列の要素をコピーするのに2次の時間がかかります。
配列を縮小するコードは示していませんが、拡張コードと非常によく似ています。
fclose()
いずれにせよ、それは単なるポインタなので、それらにメモリを割り当てることができますが、各ファイルポインタとfree()
メモリを忘れないでください