リスト構造見の場合で配列を使用しない場合のコードを記載します.
配列を使用する場合は, 新たにインデックス用の外部変数を設けるなどして適切な処理を追加すればできると思います.
NOTE
- 構造体の名称及び要素名を変更しています.
- 数値を入力する際に専用の関数を追加.
未対処の項目
- データを挿入・削除した際のデータの番号(no)の指定
以下のコードの場合, 挿入した際は強制的に加算しているため,
本来加算されるべきでない場合でも加算されてしまいます.
削除の場合は何も考慮していない.
- 諸々のエラー(noの重複やSegmentation Faultが起こる可能性があり)
C
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5
6typedef struct _data_t data_t;
7struct _data_t {
8 int no;
9
10 char name[20];
11 double height;
12 double weight;
13
14 data_t *next;
15};
16
17
18static long
19get_long_value(void) {
20 char buf[1024];
21
22 memset((void *)buf, '\0', sizeof(buf));
23 fgets((char *)buf, 1023, stdin);
24
25 return strtol(buf, NULL, 10);
26}
27
28static double
29get_double_value(void) {
30 char buf[1024];
31
32 memset((void *)buf, '\0', sizeof(buf));
33 fgets((char *)buf, 1023, stdin);
34
35 return strtod(buf, NULL);
36}
37
38
39/** 新規に data_t * を割り当て */
40data_t *
41data_new(int no) {
42 data_t *data;
43
44 if((data = (data_t *)calloc(1, sizeof(data_t))) != NULL) {
45 data->no = no;
46
47 // 名称
48 printf("No. %d name: ", no);
49 fgets((char *)data->name, 19, stdin);
50 data->name[strlen(data->name) - 1] = '\0';
51
52 // 身長
53 printf("Height: ");
54 data->height = get_double_value();
55
56 // 体重
57 printf("Weight: ");
58 data->weight = get_double_value();
59
60 data->next = NULL;
61 }
62
63 return data;
64}
65
66/** data_t * の挿入
67 * dataset: 対象のリストの任意のポインタ,
68 * no: 対象データの no
69 *
70 * 返り値
71 * 成功した場合, dataset
72 * それ以外 NULL
73 */
74data_t *
75data_insert(data_t *dataset, int no) {
76 data_t *p_data, *p_new;
77
78 if(dataset == NULL) {
79 return NULL;
80 }
81
82 for(p_data = dataset; p_data != NULL; p_data = p_data->next) {
83 if(p_data->no == no) {
84 break;
85 }
86 }
87
88 // 対象のデータが存在しない.
89 if(p_data == NULL) {
90 return NULL;
91 }
92
93
94 printf("* insert new data.\n");
95 p_new = data_new(no + 1);
96
97 p_new->next = p_data->next;
98 p_data->next = p_new;
99
100 // data->no の更新
101 for(p_data = p_new->next; p_data != NULL; p_data = p_data->next) {
102 p_data->no += 1;
103 }
104
105 return dataset;
106}
107
108/** data_t * の削除
109 * dataset: 対象のリストの任意のポインタ,
110 * no: 対象データの no
111 *
112 * 返り値
113 * 成功した場合, dataset
114 * それ以外 NULL
115 */
116data_t *
117data_delete(data_t *dataset, int no) {
118 data_t *p_pre, *p_data;
119
120
121 if(dataset == NULL) {
122 return NULL;
123 }
124
125 p_pre = NULL;
126 for(p_data = dataset; p_data != NULL; p_data = p_data->next) {
127 if(p_data->no == no) {
128 break;
129 }
130
131 p_pre = p_data;
132 }
133
134 // 該当データなし
135 if(p_data == NULL) {
136 fprintf(stderr, "該当データなし.\n");
137 return NULL;
138 }
139
140 if(p_pre == NULL) {
141 // 先頭が削除された場合
142 dataset = p_data->next;
143 } else {
144 p_pre->next = p_data->next;
145 }
146
147 // 該当項目の削除
148 memset((void *)p_data, '\0', sizeof(data_t));
149 free((void *)p_data);
150 p_data = NULL;
151
152 return dataset;
153}
154
155
156/** 指定された位置からの data_t * を解放 */
157void
158data_free(data_t *dataset) {
159 data_t *p_next;
160
161 if(dataset == NULL) {
162 return;
163 }
164
165 do {
166 //printf("%p\n", dataset);
167 p_next = dataset->next;
168
169 memset((void *)dataset, '\0', sizeof(data_t));
170 free((void *)dataset);
171
172 dataset = p_next;
173
174 } while(dataset != NULL);
175}
176
177
178/** 指定された位置からの data_t * を表示 */
179void
180data_display_all(const data_t *dataset) {
181 const data_t *p_data;
182
183 if(dataset == NULL) {
184 return;
185 }
186
187 for(p_data = dataset; p_data != NULL; p_data = p_data->next) {
188 printf("No.%2d: %s\n", p_data->no, p_data->name);
189 printf("%.1f[cm] %.1f[kg]\n\n", p_data->height, p_data->weight);
190 }
191}
192
193
194
195int
196main(int argc, char *argv[]) {
197 int i, nof_people;
198 data_t *dataset, *ds_cur;
199
200
201 printf("Please input the number of people: ");
202 nof_people = (int)get_long_value();
203
204
205 dataset = NULL;
206 ds_cur = NULL;
207
208 for(i = 0; i < nof_people; ++i) {
209 data_t *_data;
210
211 _data = data_new(i + 1);
212 if(_data == NULL) {
213 // data_t の割り当てに失敗. 必要であれば処理を追加.
214 break;
215 }
216
217 if(dataset == NULL) {
218 dataset = _data;
219 ds_cur = _data;
220 } else {
221 ds_cur->next = _data;
222 ds_cur = _data;
223 }
224 }
225
226 // テストとして以下の2行を記載
227 // 正しく処理する必要がある.
228 dataset = data_insert(dataset, 1);
229 dataset = data_delete(dataset, 1);
230
231 // 表示
232 data_display_all(dataset);
233
234 // 解放
235 data_free(dataset);
236 dataset = NULL;
237 return 0;
238}