- ベストアンサー
構造体の動的メモリについて
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NUM 10 /*生徒数*/ typedef struct data { int num; /*従業員番号*/ char name[16]; /*名前*/ int jap; /*国語の点数*/ int math; /*数学の点数*/ }data; int main(void) { data test[NUM]; /*生徒のデータ*/ FILE *fp; /*ファイル操作用*/ int i; /*配列インデックス*/ int count; /*データ分割用*/ char s[100]; /*データ読み込み用*/ char *token; /*データ分割用*/ char *data[6]; /*分割データ保存用*/ fp = fopen ("data1.txt","r"); for (i=0; i<NUM; i++){ fgets (s, sizeof(s), fp); /*dataファイルから1行読み込み*/ token = strtok(s, ","); /*読み込んだデータを","で分割する*/ count=0; while (token != NULL){ data[count] = token; /*分割したデータを配列へ入れる*/ token = strtok(NULL,","); count++; } test[i].num = atoi(data[0]); strcpy (test[i].name, data[1]); test[i].jap = atoi(data[2]); test[i].math = atoi(data[3]); } fclose(fp); } このプログラムを構造体へのポインタの配列で管理するように変えたいのですが、どのように変更すればいいのでしょうか。 条件として、個人データを格納するメモリ領域とポインタの配列のメモリ領域は動的に確保します。 初心者でよくわからないので詳しく教えていただけると助かります。よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
こんにちわ。 data * datap, * p; datap = (data *)malloc(sizeof(data) * NUM); /* メモリ確保 */ p = datap; /* 先頭ポインタ取得 */ for(i = 0; i < NUM; i++) { ・・・ p->num = atoi(data[0]); strcpy (p->name, data[1]); p->jap = atoi(data[2]); p->math = atoi(data[3]); p++; } で、いけるんじゃないですか? 構造体のポインタの配列を、わざわざ使う必要も無いと思います。 NUMが可変の場合(ファイル行数によって変わる)、ファイルをまず最後まで読み込み、行数を取得した後で その行数 * sizeof(data)で、mallocすれば、余計なメモリを確保せずに済みます。 これが最善の方法かは、知りません(汗)
その他の回答 (1)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
ポインタの配列を動的に確保しようと思ったら、配列のサイズを確保する前に知る必要があるので、例えば生徒数を読み込むような変更をする必要があると思います。 逆に #define NUM 10 のように固定になっているなら、動的にポインタの配列を確保する必要はなくて、あらかじめ確保すればいいと思います。 さて、配列のサイズが決まれば data **配列 = calloc(size, sizeof(data*)) のように(あるいは、mallocを使って)確保すればいいです。 それぞれの個人データは、読込の度に 配列[counter++]=malloc(sizeof(data)); のようにして確保してそのポインタを配列に格納すればよいです。