質問編集履歴

4

修正

2018/01/27 13:05

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -10,6 +10,32 @@
10
10
 
11
11
  さっぱりわかりません。
12
12
 
13
+
14
+
15
+ if (&((*p)->next) == q || &((*q)->next) == p)のところで
16
+
17
+ &((*p)->next) == q、&((*q)->next) == pは具体的にどういうことなんでしょうか。
18
+
19
+
20
+
21
+ if (s->next != 0){}の下の文r->before = s;からs->next = r;までは
22
+
23
+ if (s->next == 0){}という条件のことでしょうか。
24
+
25
+
26
+
27
+ if (s->next != 0){
28
+
29
+ s->next->before = r;
30
+
31
+ //「sの次が存在するなら、そいつの手前をrにする」と読める。
32
+
33
+         //つまり" r ← sの次 " ってゆー上り方向のリンクを張り替えたってこと。
34
+
35
+ のようなわかり易い説明をしてもらいました。
36
+
37
+
38
+
13
39
  ポインタのポインタは復習してみました。
14
40
 
15
41
  コメントを付けていますが、自分でもよくわかりません。
@@ -116,7 +142,51 @@
116
142
 
117
143
  if (s->next != 0){
118
144
 
145
+ s->next->before = r;
146
+
147
+ //「sの次が存在するなら、そいつの手前をrにする」と読める。
148
+
149
+         //つまり" r ← sの次 " ってゆー上り方向のリンクを張り替えたってこと。
150
+
151
+     }
152
+
153
+ r->before = s;
154
+
155
+ //rは*pであるから,*p->before = sである。s==*qなので
156
+
157
+ //*p->beforeに*q(これはポインタ)を代入する。
158
+
159
+
160
+
161
+ s->before = r->before;
162
+
163
+ // s->beforeに*q(これはポインタ)を代入する。
164
+
165
+
166
+
167
+ *p = s;
168
+
169
+ //sは*qだから*pに*q(これはポインタ)を代入する。
170
+
171
+
172
+
173
+ *q = s->next;
174
+
175
+ //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。
176
+
177
+
178
+
179
+ s->next = r;
180
+
119
- // sと*qはおなじである。s->nextは(*q)->nextであから
181
+ //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入す
182
+
183
+
184
+
185
+ return;
186
+
187
+ } else {
188
+
189
+ if (s->next != 0){
120
190
 
121
191
  // (*q)->nextが0でないとき
122
192
 
@@ -124,130 +194,54 @@
124
194
 
125
195
  s->next->before = r;
126
196
 
127
- //(s->next)->beforeは((*q)->next)->beforeとおなじ
128
-
129
- //rは*pと同じだから、(s->next)->before*p(これはポインタ)
197
+ // (s->next)->before=*p
130
-
198
+
131
- //を代入する。
199
+ }
132
-
133
- //上り方向のリンクを張り替えたってこと
200
+
134
-
135
- } //sの次が存在するなら、そいつの手前をrにする
136
-
137
-
138
-
139
- r->before = s;
201
+ t = s->before;
140
-
141
- //rは*pであるから,*p->before = sである。s==*qなので
202
+
142
-
143
- //*p->before*q(これはポインタ)を代入する。
203
+ // s->before==(*q)->before
204
+
205
+ // t=(*q)->before
144
206
 
145
207
 
146
208
 
147
209
  s->before = r->before;
148
210
 
149
- // s->beforeに*q(これはポインタ)を代入する。
211
+ // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
212
+
213
+
214
+
150
-
215
+ if (r->next != 0){
216
+
217
+ // (*p)->nextが0でないとき
218
+
219
+
220
+
221
+ r->next->before = s;
222
+
223
+ // (r->next)->before=*q
224
+
225
+ }
226
+
227
+ r->before = t;
228
+
229
+
230
+
231
+ t = r->next;
232
+
233
+
234
+
235
+ r->next = s->next;
236
+
237
+
238
+
151
- //
239
+ s->next = t;
152
-
153
-
240
+
241
+
154
242
 
155
243
  *p = s;
156
244
 
157
- //sは*qだから*pに*q(これはポインタ)を代入する。
158
-
159
-
160
-
161
- *q = s->next;
162
-
163
- //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。
164
-
165
-
166
-
167
- s->next = r;
168
-
169
- //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。
170
-
171
-
172
-
173
- return;
174
-
175
- } else {
176
-
177
- if (s->next != 0){
178
-
179
- // (*q)->nextが0でないとき
180
-
181
-
182
-
183
- s->next->before = r;
184
-
185
- // (s->next)->before=*p
186
-
187
- }
188
-
189
- t = s->before;
190
-
191
- // s->before==(*q)->before
192
-
193
- // t=(*q)->before
194
-
195
-
196
-
197
- s->before = r->before;
198
-
199
- // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
200
-
201
-
202
-
203
- if (r->next != 0){
204
-
205
- // (*p)->nextが0でないとき
206
-
207
-
208
-
209
- r->next->before = s;
210
-
211
- // (r->next)->before=*q
212
-
213
- }
214
-
215
- r->before = t;
216
-
217
- // r->before==(*p)->before
218
-
219
- // t=s->before
220
-
221
- // r->beforeにs->before==(*q)->before(これはポインタ)を代入する。
222
-
223
-
224
-
225
- t = r->next;
226
-
227
- // r->next==(*p)->nextが0でないときであるから
228
-
229
- // t=(*p)->next
230
-
231
-
232
-
233
- r->next = s->next;
234
-
235
- // s->next==(*q)->next
236
-
237
- // r->next =(*q)->next
238
-
239
-
240
-
241
- s->next = t;
242
-
243
- // t=(*p)->next
244
-
245
- // s->next=(*p)->next
246
-
247
-
248
-
249
- *p = s;
250
-
251
245
  *q = r;
252
246
 
253
247
  }

3

コードの修正

2018/01/27 13:05

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,6 @@
1
- 構造体のデータをリストを使ってソートしているコードがあるんですが、
1
+ リストの構造体のデータをソートしているコードがあるんですが、
2
-
2
+
3
- exchange()関数のところを図を使って書こうとおもったのですが、うまくいきません。
3
+ exchange()関数のところを図を使って書こうとったのですが、うまくいきません。
4
4
 
5
5
  図で説明してもらえませんか。
6
6
 
@@ -8,9 +8,13 @@
8
8
 
9
9
  *p,*qをr、sで保存しているところまでは分かるのですが、そのあとが
10
10
 
11
+ さっぱりわかりません。
12
+
11
- さっぱりわかりません。ポインタのポインタっかり理解出来いないので、
13
+ ポインタのポインタは復習してみました。
14
+
12
-
15
+ コメントを付けていますが、自分でもよくわかりません。
16
+
13
- 図を描けなと思っています。いつも同じような質問で申し訳ありませんが、
17
+ いつも同じような質問で申し訳ありませんが、どなたか説明をしてもらえませんか。
14
18
 
15
19
  よろしくお願いいたします。
16
20
 
@@ -18,19 +22,9 @@
18
22
 
19
23
  ```ここに言語を入力
20
24
 
21
- //リスト構造
22
-
23
- // 電話帳プログラム解説
25
+ // 電話帳プログラム
24
-
25
- #include <stdio.h>
26
+
26
-
27
- #include <stdlib.h>
27
+
28
-
29
- #include <string.h>
30
-
31
- #include <assert.h> //
32
-
33
-
34
28
 
35
29
  #define N 256
36
30
 
@@ -56,89 +50,205 @@
56
50
 
57
51
 
58
52
 
53
+ //(*head)->nameと(*head)->next)のnameとを比べて
54
+
59
- void data_show(struct address* head);
55
+ //小さいほうのポインタのポインタを返却値にしている。
60
-
61
- void data_add(struct address** head);
56
+
62
-
63
- void data_delete(struct address** head);
57
+ struct address **listmin(struct address **head) {
64
-
58
+
65
- void data_sort(struct address** head);
59
+ struct address **p;
66
-
67
- void data_write(struct address* head);
60
+
68
-
69
-
70
-
71
- void data_amend(struct address* head);
72
-
73
- void data_search(struct address* head);
74
-
75
-
76
-
77
- void chop(char *p){
78
-
79
- for (; *p; p++)
61
+ if (*head == 0)
80
-
62
+
81
- ;
63
+ return 0;
64
+
82
-
65
+ if ((*head)->next == 0)
66
+
83
-
67
+ return head;
68
+
84
-
69
+ if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
70
+
71
+ // #include <string.h>
72
+
73
+ // int strcmp( const char *str1 , const char *str2 );
74
+
85
- p--; // *pが\0とりfor()抜けるとここに来る
75
+ // str1<str2らば負の値返す
86
-
87
- //ポインタを1個戻して,\0 の前が'\r'か'\n'どうか調べるため。
76
+
88
-
89
-
90
-
91
- while (*p == '\r' || *p == '\n')
92
-
93
- *(p--) = 0;
77
+ return head;
78
+
94
-
79
+ else
80
+
95
-
81
+ return p;
96
82
 
97
83
  }
98
84
 
99
85
 
100
86
 
101
- void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
87
+ void exchange(struct address **p, struct address **q)
102
88
 
103
89
  {
104
90
 
105
- struct address *p;
91
+ struct address *r, *s, *t;
92
+
106
-
93
+ assert(*p != 0 && *q != 0);
94
+
95
+ //assertマクロは関数形式マクロで、引数に偽(すなわち0)が指定されると、
96
+
97
+ //ソースファイル名や行番号等の情報を標準エラー出力に出力し、
98
+
99
+ //プログラムを終了させます。
100
+
101
+ if (p == q)
102
+
103
+ return;
104
+
105
+
106
+
107
+ r = *p; s = *q;
108
+
107
- if ((p = malloc(sizeof(struct address))) != 0) {
109
+ if (&((*p)->next) == q || &((*q)->next) == p) {
110
+
108
-
111
+ // (*p)はポインタで,(*p)->nextも次のポインタである。
112
+
109
-
113
+ // q(ポインタのポインタ)と(*p)->nextを比較するには&((*p)->next)とする。
110
-
114
+
115
+
116
+
111
- strcpy(p->name, name);
117
+ if (s->next != 0){
118
+
112
-
119
+ // sと*qはおなじである。s->nextは(*q)->nextであるから
120
+
113
-
121
+ // (*q)->nextが0でないとき
114
-
122
+
123
+
124
+
115
- strcpy(p->address, address);
125
+ s->next->before = r;
116
-
126
+
117
- //文字型配列 p->address に文字列 address を '\0' までコピーします。
127
+ //(s->next)->beforeは((*q)->next)->beforeとおなじ
128
+
129
+ //rは*pと同じだから、(s->next)->beforeに*p(これはポインタ)
130
+
131
+ //を代入する。
132
+
133
+ //上り方向のリンクを張り替えたってこと
134
+
135
+ } //sの次が存在するなら、そいつの手前をrにする
118
136
 
119
137
 
120
138
 
139
+ r->before = s;
140
+
141
+ //rは*pであるから,*p->before = sである。s==*qなので
142
+
143
+ //*p->beforeに*q(これはポインタ)を代入する。
144
+
145
+
146
+
147
+ s->before = r->before;
148
+
149
+ // s->beforeに*q(これはポインタ)を代入する。
150
+
151
+ //
152
+
153
+
154
+
155
+ *p = s;
156
+
157
+ //sは*qだから*pに*q(これはポインタ)を代入する。
158
+
159
+
160
+
121
- strcpy(p->tel, tel);
161
+ *q = s->next;
122
-
123
- //文字型配列 p->number に文字列 number を '\0' までコピーします。
162
+
124
-
125
-
126
-
127
- strcpy(p->mail, mail);
128
-
129
- //文字型配列 p->mail 文字列 mail '\0' までコピーします。
163
+ //s->nextは(*q)->nextであるから*q(*q)->next(これはポインタ)代入
130
-
131
-
132
-
164
+
165
+
166
+
133
- p->next = *head;
167
+ s->next = r;
168
+
134
-
169
+ //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。
170
+
171
+
172
+
173
+ return;
174
+
175
+ } else {
176
+
135
- if (p->next != 0)
177
+ if (s->next != 0){
178
+
136
-
179
+ // (*q)->nextが0でないとき
180
+
181
+
182
+
137
- p->next->before = p;
183
+ s->next->before = r;
184
+
138
-
185
+ // (s->next)->before=*p
186
+
187
+ }
188
+
189
+ t = s->before;
190
+
191
+ // s->before==(*q)->before
192
+
193
+ // t=(*q)->before
194
+
195
+
196
+
197
+ s->before = r->before;
198
+
199
+ // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
200
+
201
+
202
+
203
+ if (r->next != 0){
204
+
205
+ // (*p)->nextが0でないとき
206
+
207
+
208
+
209
+ r->next->before = s;
210
+
211
+ // (r->next)->before=*q
212
+
213
+ }
214
+
139
- p->before = 0;
215
+ r->before = t;
216
+
140
-
217
+ // r->before==(*p)->before
218
+
219
+ // t=s->before
220
+
221
+ // r->beforeにs->before==(*q)->before(これはポインタ)を代入する。
222
+
223
+
224
+
225
+ t = r->next;
226
+
227
+ // r->next==(*p)->nextが0でないときであるから
228
+
229
+ // t=(*p)->next
230
+
231
+
232
+
233
+ r->next = s->next;
234
+
235
+ // s->next==(*q)->next
236
+
237
+ // r->next =(*q)->next
238
+
239
+
240
+
241
+ s->next = t;
242
+
243
+ // t=(*p)->next
244
+
245
+ // s->next=(*p)->next
246
+
247
+
248
+
141
- *head = p;
249
+ *p = s;
250
+
251
+ *q = r;
142
252
 
143
253
  }
144
254
 
@@ -146,410 +256,50 @@
146
256
 
147
257
 
148
258
 
149
-
150
-
151
- struct address **listmin(struct address **head) {
259
+ void data_sort(struct address **head)
260
+
152
-
261
+ {
262
+
153
- struct address **p;
263
+ struct address **p;
154
-
264
+
155
- if (*head == 0)
265
+ if (*head != 0) {
266
+
156
-
267
+ for (;;) {
268
+
269
+ p = listmin(head);
270
+
271
+ //(*head)->nameと(*head)->next)のnameとを比べて
272
+
273
+ //小さいほうのポインタのポインタを返却値にしている。
274
+
275
+ //帰ってきたhead(小さいほうのポインタのポインタ),または
276
+
277
+ //p(小さいほうのポインタのポインタ)
278
+
279
+
280
+
157
- return 0;
281
+ if (p == 0)
282
+
158
-
283
+ break;
284
+
285
+
286
+
287
+ exchange(head, p);
288
+
289
+ //大小を入れ替える
290
+
291
+
292
+
159
- if ((*head)->next == 0)
293
+ head = &((*head)->next);
160
-
161
- return head;
294
+
162
-
163
- if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
164
-
165
- // #include <string.h>
166
-
167
- // int strcmp( const char *str1 , const char *str2 );
168
-
169
- // str1<str2ならば負の値を返す。
170
-
171
- return head;
172
-
173
- else
295
+ }
174
-
296
+
175
- return p;
297
+ }
176
298
 
177
299
  }
178
300
 
179
301
 
180
302
 
181
- void exchange(struct address **p, struct address **q)
182
-
183
- {
184
-
185
- struct address *r, *s, *t;
186
-
187
- assert(*p != 0 && *q != 0);
188
-
189
-
190
-
191
- if (p == q)
192
-
193
- return;
194
-
195
-
196
-
197
- r = *p; s = *q;
198
-
199
- if (&((*p)->next) == q || &((*q)->next) == p) {
200
-
201
- // (*p)はポインタで,(*p)->nextも次のポインタである。
202
-
203
- // q(ポインタのポインタ)と(*p)->nextを比較するには&((*p)->next)とする。
204
-
205
-
206
-
207
- if (s->next != 0){
208
-
209
- // sと*qはおなじである。s->nextは(*q)->nextであるから
210
-
211
- // (*q)->nextが0でないとき
212
-
213
-
214
-
215
- s->next->before = r;
216
-
217
- //(s->next)->beforeは((*q)->next)->beforeとおなじ
218
-
219
- //rは*pと同じだから、(s->next)->beforeに*p(これはポインタ)を代入する。
220
-
221
- }
222
-
223
- r->before = s;
224
-
225
- //rは*pであるから,*p->before = sである。s==*qなので
226
-
227
- //*p->beforeに*q(これはポインタ)を代入する。
228
-
229
-
230
-
231
- s->before = r->before;
232
-
233
- // s->beforeに*q(これはポインタ)を代入する。
234
-
235
- //
236
-
237
-
238
-
239
- *p = s;
240
-
241
- //sは*qだから*pに*q(これはポインタ)を代入する。
242
-
243
-
244
-
245
- *q = s->next;
246
-
247
- //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。
248
-
249
-
250
-
251
- s->next = r;
252
-
253
- //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。
254
-
255
-
256
-
257
- return;
258
-
259
- } else {
260
-
261
- if (s->next != 0){
262
-
263
- // (*q)->nextが0でないとき
264
-
265
-
266
-
267
- s->next->before = r;
268
-
269
- // (s->next)->before=*p
270
-
271
- }
272
-
273
- t = s->before;
274
-
275
- // s->before==(*q)->before
276
-
277
- // t=(*q)->before
278
-
279
-
280
-
281
- s->before = r->before;
282
-
283
- // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
284
-
285
-
286
-
287
- if (r->next != 0){
288
-
289
- // (*p)->nextが0でないとき
290
-
291
-
292
-
293
- r->next->before = s;
294
-
295
- // (r->next)->before=*q
296
-
297
- }
298
-
299
- r->before = t;
300
-
301
- // r->before==(*p)->before
302
-
303
- // t=s->before
304
-
305
- // r->beforeにs->before==(*q)->before(これはポインタ)を代入する。
306
-
307
-
308
-
309
- t = r->next;
310
-
311
- // r->next==(*p)->nextが0でないときであるから
312
-
313
- // t=(*p)->next
314
-
315
-
316
-
317
- r->next = s->next;
318
-
319
- // s->next==(*q)->next
320
-
321
- // r->next =(*q)->next
322
-
323
-
324
-
325
- s->next = t;
326
-
327
- // t=(*p)->next
328
-
329
- // s->next=(*p)->next
330
-
331
-
332
-
333
- *p = s;
334
-
335
- *q = r;
336
-
337
- }
338
-
339
- }
340
-
341
-
342
-
343
- void data_sort(struct address **head)
344
-
345
- {
346
-
347
- struct address **p;
348
-
349
- if (*head != 0) {
350
-
351
- for (;;) {
352
-
353
- p = listmin(head);
354
-
355
- if (p == 0)
356
-
357
- break;
358
-
359
-
360
-
361
- exchange(head, p);
362
-
363
- head = &((*head)->next);
364
-
365
- }
366
-
367
- }
368
-
369
- }
370
-
371
-
372
-
373
- void release(struct address **head) {
374
-
375
- if (*head != 0) {
376
-
377
- release( &((*head)->next) );
378
-
379
- free(*head);
380
-
381
- *head = 0;
382
-
383
- }
384
-
385
- }
386
-
387
-
388
-
389
- int main() {
390
-
391
- struct address *head;
392
-
393
- FILE* fp;
394
-
395
- static char buff[N], name[N], address[N], tel[N], mail[N];
396
-
397
- char *token=",";
398
-
399
- int select;
400
-
401
-
402
-
403
- head = 0;
404
-
405
-
406
-
407
- if ((fp = fopen(FILENAME,"r")) != 0) {
408
-
409
- while(fgets(buff, N, fp) != 0){
410
-
411
- //本当の大元の文字列を書き換えないようにするために
412
-
413
- //bufを確保してコピーし、それをstrtok()の引数にしている。
414
-
415
- char *p;
416
-
417
- chop(buff);
418
-
419
- printf( "ファイルから読んだ文字列:%s\n", buff );
420
-
421
-
422
-
423
- p = strtok(buff, token);
424
-
425
- if ( p != NULL ) {
426
-
427
- strcpy(name, p);
428
-
429
- } else {
430
-
431
- printf( "氏名の切り出しに失敗しました。\n");
432
-
433
- break;
434
-
435
- }
436
-
437
-
438
-
439
- p = strtok(NULL, token);
440
-
441
- if ( p != NULL ) {
442
-
443
- strcpy(address, p);
444
-
445
- } else {
446
-
447
- printf( "住所の切り出しに失敗しました。\n");
448
-
449
- break;
450
-
451
- }
452
-
453
-
454
-
455
- p = strtok(NULL, token);
456
-
457
- if ( p != NULL ) {
458
-
459
- strcpy(tel, p);
460
-
461
- } else {
462
-
463
- printf( "電話番号の切り出しに失敗しました。\n");
464
-
465
- break;
466
-
467
- }
468
-
469
-
470
-
471
- p = strtok(NULL, token);
472
-
473
- if ( p != NULL ) {
474
-
475
- strcpy(mail, p);
476
-
477
- } else {
478
-
479
- printf( "メールアドレスの切り出しに失敗しました。\n");
480
-
481
- break;
482
-
483
- }
484
-
485
- list_add(&head, name, address, tel, mail);
486
-
487
- }
488
-
489
- fclose(fp);
490
-
491
- }
492
-
493
- while(select != 0){
494
-
495
- printf(" 1:ソ\ート 2:削除 3:追加 4:全体表\示 5:修正 6:検索 0:終了 \n");
496
-
497
-
498
-
499
- printf("●メニューを入力して下さい ");
500
-
501
- fgets(buff, N, stdin);
502
-
503
-
504
-
505
- if (sscanf(buff, "%d", &select) != 1)
506
-
507
-
508
-
509
- select = -1;
510
-
511
-
512
-
513
- switch(select){
514
-
515
- case 1:
516
-
517
- data_sort(&head);
518
-
519
- data_show(head);
520
-
521
- break;
522
-
523
-
524
-
525
- ......省略.....
526
-
527
-
528
-
529
- case 0:
530
-
531
- printf("quit.\n");
532
-
533
- break;
534
-
535
- default:
536
-
537
- printf("bad command, once more.\n");
538
-
539
- break;
540
-
541
- }
542
-
543
- }
544
-
545
- release(&head);
546
-
547
- return 0;
548
-
549
- }
550
-
551
-
552
-
553
303
  データ
554
304
 
555
305
  address.csv

2

コードの修正

2018/01/27 12:34

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -18,8 +18,6 @@
18
18
 
19
19
  ```ここに言語を入力
20
20
 
21
- コード
22
-
23
21
  //リスト構造
24
22
 
25
23
  // 電話帳プログラム解説
@@ -100,568 +98,450 @@
100
98
 
101
99
 
102
100
 
103
- void data_search(struct address* head)
101
+ void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
104
102
 
105
103
  {
106
104
 
107
- char buff[N], dummy[N];
105
+ struct address *p;
106
+
108
-
107
+ if ((p = malloc(sizeof(struct address))) != 0) {
108
+
109
+
110
+
111
+ strcpy(p->name, name);
112
+
113
+
114
+
115
+ strcpy(p->address, address);
116
+
117
+ //文字型配列 p->address に文字列 address を '\0' までコピーします。
118
+
119
+
120
+
121
+ strcpy(p->tel, tel);
122
+
109
- char *target[] = { "氏名","住所", "電話番号","メルアドレス"};
123
+ //文字型配列 p->number に文字列 number '\0' までコピします。
124
+
125
+
126
+
110
-
127
+ strcpy(p->mail, mail);
128
+
129
+ //文字型配列 p->mail に文字列 mail を '\0' までコピーします。
130
+
131
+
132
+
133
+ p->next = *head;
134
+
111
- int i,cnt=0,count=0;
135
+ if (p->next != 0)
136
+
112
-
137
+ p->next->before = p;
138
+
139
+ p->before = 0;
140
+
141
+ *head = p;
142
+
143
+ }
144
+
145
+ }
146
+
147
+
148
+
149
+
150
+
151
+ struct address **listmin(struct address **head) {
152
+
153
+ struct address **p;
154
+
155
+ if (*head == 0)
156
+
157
+ return 0;
158
+
159
+ if ((*head)->next == 0)
160
+
161
+ return head;
162
+
163
+ if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
164
+
165
+ // #include <string.h>
166
+
167
+ // int strcmp( const char *str1 , const char *str2 );
168
+
169
+ // str1<str2ならば負の値を返す。
170
+
171
+ return head;
172
+
173
+ else
174
+
175
+ return p;
176
+
177
+ }
178
+
179
+
180
+
181
+ void exchange(struct address **p, struct address **q)
182
+
183
+ {
184
+
113
- struct address *t = head;
185
+ struct address *r, *s, *t;
186
+
187
+ assert(*p != 0 && *q != 0);
114
188
 
115
189
 
116
190
 
191
+ if (p == q)
192
+
193
+ return;
194
+
195
+
196
+
197
+ r = *p; s = *q;
198
+
199
+ if (&((*p)->next) == q || &((*q)->next) == p) {
200
+
201
+ // (*p)はポインタで,(*p)->nextも次のポインタである。
202
+
203
+ // q(ポインタのポインタ)と(*p)->nextを比較するには&((*p)->next)とする。
204
+
205
+
206
+
207
+ if (s->next != 0){
208
+
209
+ // sと*qはおなじである。s->nextは(*q)->nextであるから
210
+
211
+ // (*q)->nextが0でないとき
212
+
213
+
214
+
215
+ s->next->before = r;
216
+
217
+ //(s->next)->beforeは((*q)->next)->beforeとおなじ
218
+
219
+ //rは*pと同じだから、(s->next)->beforeに*p(これはポインタ)を代入する。
220
+
221
+ }
222
+
223
+ r->before = s;
224
+
225
+ //rは*pであるから,*p->before = sである。s==*qなので
226
+
227
+ //*p->beforeに*q(これはポインタ)を代入する。
228
+
229
+
230
+
231
+ s->before = r->before;
232
+
233
+ // s->beforeに*q(これはポインタ)を代入する。
234
+
235
+ //
236
+
237
+
238
+
239
+ *p = s;
240
+
241
+ //sは*qだから*pに*q(これはポインタ)を代入する。
242
+
243
+
244
+
245
+ *q = s->next;
246
+
247
+ //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。
248
+
249
+
250
+
251
+ s->next = r;
252
+
253
+ //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。
254
+
255
+
256
+
257
+ return;
258
+
259
+ } else {
260
+
261
+ if (s->next != 0){
262
+
263
+ // (*q)->nextが0でないとき
264
+
265
+
266
+
267
+ s->next->before = r;
268
+
269
+ // (s->next)->before=*p
270
+
271
+ }
272
+
273
+ t = s->before;
274
+
275
+ // s->before==(*q)->before
276
+
277
+ // t=(*q)->before
278
+
279
+
280
+
281
+ s->before = r->before;
282
+
283
+ // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
284
+
285
+
286
+
287
+ if (r->next != 0){
288
+
289
+ // (*p)->nextが0でないとき
290
+
291
+
292
+
293
+ r->next->before = s;
294
+
295
+ // (r->next)->before=*q
296
+
297
+ }
298
+
299
+ r->before = t;
300
+
301
+ // r->before==(*p)->before
302
+
303
+ // t=s->before
304
+
305
+ // r->beforeにs->before==(*q)->before(これはポインタ)を代入する。
306
+
307
+
308
+
309
+ t = r->next;
310
+
311
+ // r->next==(*p)->nextが0でないときであるから
312
+
313
+ // t=(*p)->next
314
+
315
+
316
+
317
+ r->next = s->next;
318
+
319
+ // s->next==(*q)->next
320
+
321
+ // r->next =(*q)->next
322
+
323
+
324
+
325
+ s->next = t;
326
+
327
+ // t=(*p)->next
328
+
329
+ // s->next=(*p)->next
330
+
331
+
332
+
333
+ *p = s;
334
+
335
+ *q = r;
336
+
337
+ }
338
+
339
+ }
340
+
341
+
342
+
343
+ void data_sort(struct address **head)
344
+
345
+ {
346
+
347
+ struct address **p;
348
+
349
+ if (*head != 0) {
350
+
117
- while (1) {
351
+ for (;;) {
352
+
118
-
353
+ p = listmin(head);
354
+
355
+ if (p == 0)
356
+
357
+ break;
358
+
359
+
360
+
361
+ exchange(head, p);
362
+
363
+ head = &((*head)->next);
364
+
365
+ }
366
+
367
+ }
368
+
369
+ }
370
+
371
+
372
+
373
+ void release(struct address **head) {
374
+
375
+ if (*head != 0) {
376
+
377
+ release( &((*head)->next) );
378
+
379
+ free(*head);
380
+
381
+ *head = 0;
382
+
383
+ }
384
+
385
+ }
386
+
387
+
388
+
389
+ int main() {
390
+
391
+ struct address *head;
392
+
393
+ FILE* fp;
394
+
119
- puts("何で探しますか?\n1.氏名 2.住所 3.電話番号 4.メールアドレス");
395
+ static char buff[N], name[N], address[N], tel[N], mail[N];
120
-
396
+
121
- scanf("%d", &i);
397
+ char *token=",";
398
+
399
+ int select;
400
+
401
+
402
+
403
+ head = 0;
404
+
405
+
406
+
407
+ if ((fp = fopen(FILENAME,"r")) != 0) {
408
+
409
+ while(fgets(buff, N, fp) != 0){
410
+
411
+ //本当の大元の文字列を書き換えないようにするために
412
+
413
+ //bufを確保してコピーし、それをstrtok()の引数にしている。
414
+
415
+ char *p;
416
+
417
+ chop(buff);
418
+
419
+ printf( "ファイルから読んだ文字列:%s\n", buff );
122
420
 
123
421
 
124
422
 
423
+ p = strtok(buff, token);
424
+
425
+ if ( p != NULL ) {
426
+
125
- gets(dummy);
427
+ strcpy(name, p);
428
+
126
-
429
+ } else {
430
+
431
+ printf( "氏名の切り出しに失敗しました。\n");
432
+
433
+ break;
434
+
435
+ }
436
+
437
+
438
+
439
+ p = strtok(NULL, token);
440
+
441
+ if ( p != NULL ) {
442
+
443
+ strcpy(address, p);
444
+
445
+ } else {
446
+
447
+ printf( "住所の切り出しに失敗しました。\n");
448
+
449
+ break;
450
+
451
+ }
452
+
453
+
454
+
455
+ p = strtok(NULL, token);
456
+
457
+ if ( p != NULL ) {
458
+
459
+ strcpy(tel, p);
460
+
461
+ } else {
462
+
463
+ printf( "電話番号の切り出しに失敗しました。\n");
464
+
465
+ break;
466
+
467
+ }
468
+
469
+
470
+
471
+ p = strtok(NULL, token);
472
+
473
+ if ( p != NULL ) {
474
+
475
+ strcpy(mail, p);
476
+
477
+ } else {
478
+
479
+ printf( "メールアドレスの切り出しに失敗しました。\n");
480
+
481
+ break;
482
+
483
+ }
484
+
127
- if (1 <= i && i <= 4) break;
485
+ list_add(&head, name, address, tel, mail);
128
486
 
129
487
  }
130
488
 
489
+ fclose(fp);
490
+
491
+ }
492
+
493
+ while(select != 0){
494
+
495
+ printf(" 1:ソ\ート 2:削除 3:追加 4:全体表\示 5:修正 6:検索 0:終了 \n");
496
+
497
+
498
+
131
- printf("%sを入力して下さい:", target[--i]);
499
+ printf("●メニューを入力して下さい ");
132
-
500
+
133
- gets(buff);
501
+ fgets(buff, N, stdin);
134
-
502
+
503
+
504
+
135
- while (t != NULL) {
505
+ if (sscanf(buff, "%d", &select) != 1)
136
-
506
+
507
+
508
+
137
- switch (i) {
509
+ select = -1;
138
-
139
- case 0: // 氏名
140
-
141
- if (!strcmp(t->name, buff)) goto print;
142
-
143
- break;
144
510
 
145
511
 
146
512
 
513
+ switch(select){
514
+
515
+ case 1:
516
+
147
- case 1: // 住所
517
+ data_sort(&head);
148
-
518
+
149
- if (!strcmp(t->address, buff)) goto print;
519
+ data_show(head);
150
-
520
+
151
- break;
521
+ break;
152
522
 
153
523
 
154
524
 
525
+ ......省略.....
526
+
527
+
528
+
155
- case 2: // 電話番号
529
+ case 0:
156
-
530
+
157
- if (!strcmp(t->tel, buff)) goto print;
531
+ printf("quit.\n");
158
-
532
+
159
- break;
533
+ break;
160
-
161
-
162
-
534
+
163
- case 3: // mail
535
+ default:
164
-
536
+
165
- if (!strcmp(t->mail, buff)) goto print;
537
+ printf("bad command, once more.\n");
166
-
538
+
167
- break;
539
+ break;
168
-
169
-
170
-
171
- default: // no condition
540
+
172
-
173
- break;
174
-
175
- }
541
+ }
176
-
177
- t = t->next;
178
-
179
- cnt++;
180
-
181
- continue;
182
-
183
-
184
-
185
- print:;
186
-
187
- printf("%d: 氏名:%s 住所:%s 電話番号:%s メールアドレス:%s\n",
188
-
189
- ++cnt, t->name, t->address, t->tel,t->mail);
190
-
191
- t = t->next;
192
-
193
- count++;
194
-
195
-
196
-
197
- }
198
-
199
- printf("%d件見つかりました\n", count);
200
-
201
- }
202
-
203
-
204
-
205
- void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
206
-
207
- {
208
-
209
- struct address *p;
210
-
211
- if ((p = malloc(sizeof(struct address))) != 0) {
212
-
213
-
214
-
215
- strcpy(p->name, name);
216
-
217
-
218
-
219
- strcpy(p->address, address);
220
-
221
- //文字型配列 p->address に文字列 address を '\0' までコピーします。
222
-
223
-
224
-
225
- strcpy(p->tel, tel);
226
-
227
- //文字型配列 p->number に文字列 number を '\0' までコピーします。
228
-
229
-
230
-
231
- strcpy(p->mail, mail);
232
-
233
- //文字型配列 p->mail に文字列 mail を '\0' までコピーします。
234
-
235
-
236
-
237
- p->next = *head;
238
-
239
- if (p->next != 0)
240
-
241
- p->next->before = p;
242
-
243
- p->before = 0;
244
-
245
- *head = p;
246
-
247
- }
248
-
249
- }
250
-
251
-
252
-
253
- void data_show(struct address *head) {
254
-
255
- if (head != 0) {
256
-
257
- printf(" %s, %s, %s, %s\n", head->name, head->address, head->tel, head->mail);
258
-
259
- data_show(head->next);
260
542
 
261
543
  }
262
544
 
263
- }
264
-
265
-
266
-
267
- struct address **listmin(struct address **head) {
268
-
269
- struct address **p;
270
-
271
- if (*head == 0)
272
-
273
- return 0;
274
-
275
- if ((*head)->next == 0)
276
-
277
- return head;
278
-
279
- if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
280
-
281
- // #include <string.h>
282
-
283
- // int strcmp( const char *str1 , const char *str2 );
284
-
285
- // str1<str2ならば負の値を返す。
286
-
287
- return head;
288
-
289
- else
290
-
291
- return p;
292
-
293
- }
294
-
295
-
296
-
297
- void exchange(struct address **p, struct address **q)
298
-
299
- {
300
-
301
- struct address *r, *s, *t;
302
-
303
- assert(*p != 0 && *q != 0);
304
-
305
-
306
-
307
- if (p == q)
308
-
309
- return;
310
-
311
-
312
-
313
- r = *p; s = *q;
314
-
315
- if (&((*p)->next) == q || &((*q)->next) == p) {
316
-
317
- // (*p)はポインタで,(*p)->nextも次のポインタである。
318
-
319
- // q(ポインタのポインタ)と(*p)->nextを比較するには&((*p)->next)とする。
320
-
321
-
322
-
323
- if (s->next != 0){
324
-
325
- // sと*qはおなじである。s->nextは(*q)->nextであるから
326
-
327
- // (*q)->nextが0でないとき
328
-
329
-
330
-
331
- s->next->before = r;
332
-
333
- //(s->next)->beforeは((*q)->next)->beforeとおなじ
334
-
335
- //rは*pと同じだから、(s->next)->beforeに*p(これはポインタ)を代入する。
336
-
337
- }
338
-
339
- r->before = s;
340
-
341
- //rは*pであるから,*p->before = sである。s==*qなので
342
-
343
- //*p->beforeに*q(これはポインタ)を代入する。
344
-
345
-
346
-
347
- s->before = r->before;
348
-
349
- // s->beforeに*q(これはポインタ)を代入する。
350
-
351
- //
352
-
353
-
354
-
355
- *p = s;
356
-
357
- //sは*qだから*pに*q(これはポインタ)を代入する。
358
-
359
-
360
-
361
- *q = s->next;
362
-
363
- //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。
364
-
365
-
366
-
367
- s->next = r;
368
-
369
- //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。
370
-
371
-
372
-
373
- return;
374
-
375
- } else {
376
-
377
- if (s->next != 0){
378
-
379
- // (*q)->nextが0でないとき
380
-
381
-
382
-
383
- s->next->before = r;
384
-
385
- // (s->next)->before=*p
386
-
387
- }
388
-
389
- t = s->before;
390
-
391
- // s->before==(*q)->before
392
-
393
- // t=(*q)->before
394
-
395
-
396
-
397
- s->before = r->before;
398
-
399
- // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
400
-
401
-
402
-
403
- if (r->next != 0){
404
-
405
- // (*p)->nextが0でないとき
406
-
407
-
408
-
409
- r->next->before = s;
410
-
411
- // (r->next)->before=*q
412
-
413
- }
414
-
415
- r->before = t;
416
-
417
- // r->before==(*p)->before
418
-
419
- // t=s->before
420
-
421
- // r->beforeにs->before==(*q)->before(これはポインタ)を代入する。
422
-
423
-
424
-
425
- t = r->next;
426
-
427
- // r->next==(*p)->nextが0でないときであるから
428
-
429
- // t=(*p)->next
430
-
431
-
432
-
433
- r->next = s->next;
434
-
435
- // s->next==(*q)->next
436
-
437
- // r->next =(*q)->next
438
-
439
-
440
-
441
- s->next = t;
442
-
443
- // t=(*p)->next
444
-
445
- // s->next=(*p)->next
446
-
447
-
448
-
449
- *p = s;
450
-
451
- *q = r;
452
-
453
- }
454
-
455
- }
456
-
457
-
458
-
459
- void data_sort(struct address **head)
460
-
461
- {
462
-
463
- struct address **p;
464
-
465
- if (*head != 0) {
466
-
467
- for (;;) {
468
-
469
- p = listmin(head);
470
-
471
- if (p == 0)
472
-
473
- break;
474
-
475
-
476
-
477
- exchange(head, p);
478
-
479
- head = &((*head)->next);
480
-
481
- }
482
-
483
- }
484
-
485
- }
486
-
487
-
488
-
489
- void release(struct address **head) {
490
-
491
- if (*head != 0) {
492
-
493
- release( &((*head)->next) );
494
-
495
- free(*head);
496
-
497
- *head = 0;
498
-
499
- }
500
-
501
- }
502
-
503
-
504
-
505
- int main() {
506
-
507
- struct address *head;
508
-
509
- FILE* fp;
510
-
511
- static char buff[N], name[N], address[N], tel[N], mail[N];
512
-
513
- char *token=",";
514
-
515
- int select;
516
-
517
-
518
-
519
- head = 0;
520
-
521
-
522
-
523
- if ((fp = fopen(FILENAME,"r")) != 0) {
524
-
525
- while(fgets(buff, N, fp) != 0){
526
-
527
- //本当の大元の文字列を書き換えないようにするために
528
-
529
- //bufを確保してコピーし、それをstrtok()の引数にしている。
530
-
531
- char *p;
532
-
533
- chop(buff);
534
-
535
- printf( "ファイルから読んだ文字列:%s\n", buff );
536
-
537
-
538
-
539
- p = strtok(buff, token);
540
-
541
- if ( p != NULL ) {
542
-
543
- strcpy(name, p);
544
-
545
- } else {
546
-
547
- printf( "氏名の切り出しに失敗しました。\n");
548
-
549
- break;
550
-
551
- }
552
-
553
-
554
-
555
- p = strtok(NULL, token);
556
-
557
- if ( p != NULL ) {
558
-
559
- strcpy(address, p);
560
-
561
- } else {
562
-
563
- printf( "住所の切り出しに失敗しました。\n");
564
-
565
- break;
566
-
567
- }
568
-
569
-
570
-
571
- p = strtok(NULL, token);
572
-
573
- if ( p != NULL ) {
574
-
575
- strcpy(tel, p);
576
-
577
- } else {
578
-
579
- printf( "電話番号の切り出しに失敗しました。\n");
580
-
581
- break;
582
-
583
- }
584
-
585
-
586
-
587
- p = strtok(NULL, token);
588
-
589
- if ( p != NULL ) {
590
-
591
- strcpy(mail, p);
592
-
593
- } else {
594
-
595
- printf( "メールアドレスの切り出しに失敗しました。\n");
596
-
597
- break;
598
-
599
- }
600
-
601
- list_add(&head, name, address, tel, mail);
602
-
603
- }
604
-
605
- fclose(fp);
606
-
607
- }
608
-
609
- while(select != 0){
610
-
611
- printf(" 1:ソ\ート 2:削除 3:追加 4:全体表\示 5:修正 6:検索 0:終了 \n");
612
-
613
-
614
-
615
- printf("●メニューを入力して下さい ");
616
-
617
- fgets(buff, N, stdin);
618
-
619
-
620
-
621
- if (sscanf(buff, "%d", &select) != 1)
622
-
623
-
624
-
625
- select = -1;
626
-
627
-
628
-
629
- switch(select){
630
-
631
- case 1:
632
-
633
- data_sort(&head);
634
-
635
- data_show(head);
636
-
637
- break;
638
-
639
-    .....
640
-
641
- 省略
642
-
643
- .....
644
-
645
-
646
-
647
-
648
-
649
- case 0:
650
-
651
- printf("quit.\n");
652
-
653
- break;
654
-
655
- default:
656
-
657
- printf("bad command, once more.\n");
658
-
659
- break;
660
-
661
- }
662
-
663
- }
664
-
665
545
  release(&head);
666
546
 
667
547
  return 0;

1

コードの入れ替え

2018/01/25 03:33

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -20,43 +20,247 @@
20
20
 
21
21
  コード
22
22
 
23
+ //リスト構造
24
+
25
+ // 電話帳プログラム解説
26
+
23
27
  #include <stdio.h>
24
28
 
25
29
  #include <stdlib.h>
26
30
 
27
31
  #include <string.h>
28
32
 
29
- #include <assert.h>
33
+ #include <assert.h> //
34
+
35
+
36
+
37
+ #define N 256
38
+
39
+ #define FILENAME "address.csv"
40
+
41
+
42
+
43
+ struct address{
44
+
45
+ char name[N];
46
+
47
+ char address[N];
48
+
49
+ char tel[N]; // 電話番号
50
+
51
+ char mail[N];
52
+
53
+ struct address *next;
54
+
55
+ struct address *before;
56
+
57
+ };
30
58
 
31
59
 
32
60
 
33
- #define N 256
34
-
35
- #define FILENAME "address.csv"
61
+ void data_show(struct address* head);
36
-
37
-
38
-
39
- struct address{
62
+
40
-
41
- char name[N];
42
-
43
- char address[N];
44
-
45
- char tel[N]; // 電話番号
46
-
47
- char mail[N];
48
-
49
- struct address *next;
63
+ void data_add(struct address** head);
50
-
64
+
51
- struct address *before;
65
+ void data_delete(struct address** head);
52
-
53
- };
54
-
55
-
56
66
 
57
67
  void data_sort(struct address** head);
58
68
 
59
-
69
+ void data_write(struct address* head);
70
+
71
+
72
+
73
+ void data_amend(struct address* head);
74
+
75
+ void data_search(struct address* head);
76
+
77
+
78
+
79
+ void chop(char *p){
80
+
81
+ for (; *p; p++)
82
+
83
+ ;
84
+
85
+
86
+
87
+ p--; // *pが\0となりfor()を抜けるとここに来る。
88
+
89
+ //ポインタを1個戻して,\0 の前が'\r'か'\n'どうか調べるため。
90
+
91
+
92
+
93
+ while (*p == '\r' || *p == '\n')
94
+
95
+ *(p--) = 0;
96
+
97
+
98
+
99
+ }
100
+
101
+
102
+
103
+ void data_search(struct address* head)
104
+
105
+ {
106
+
107
+ char buff[N], dummy[N];
108
+
109
+ char *target[] = { "氏名","住所", "電話番号","メールアドレス"};
110
+
111
+ int i,cnt=0,count=0;
112
+
113
+ struct address *t = head;
114
+
115
+
116
+
117
+ while (1) {
118
+
119
+ puts("何で探しますか?\n1.氏名 2.住所 3.電話番号 4.メールアドレス");
120
+
121
+ scanf("%d", &i);
122
+
123
+
124
+
125
+ gets(dummy);
126
+
127
+ if (1 <= i && i <= 4) break;
128
+
129
+ }
130
+
131
+ printf("%sを入力して下さい:", target[--i]);
132
+
133
+ gets(buff);
134
+
135
+ while (t != NULL) {
136
+
137
+ switch (i) {
138
+
139
+ case 0: // 氏名
140
+
141
+ if (!strcmp(t->name, buff)) goto print;
142
+
143
+ break;
144
+
145
+
146
+
147
+ case 1: // 住所
148
+
149
+ if (!strcmp(t->address, buff)) goto print;
150
+
151
+ break;
152
+
153
+
154
+
155
+ case 2: // 電話番号
156
+
157
+ if (!strcmp(t->tel, buff)) goto print;
158
+
159
+ break;
160
+
161
+
162
+
163
+ case 3: // mail
164
+
165
+ if (!strcmp(t->mail, buff)) goto print;
166
+
167
+ break;
168
+
169
+
170
+
171
+ default: // no condition
172
+
173
+ break;
174
+
175
+ }
176
+
177
+ t = t->next;
178
+
179
+ cnt++;
180
+
181
+ continue;
182
+
183
+
184
+
185
+ print:;
186
+
187
+ printf("%d: 氏名:%s 住所:%s 電話番号:%s メールアドレス:%s\n",
188
+
189
+ ++cnt, t->name, t->address, t->tel,t->mail);
190
+
191
+ t = t->next;
192
+
193
+ count++;
194
+
195
+
196
+
197
+ }
198
+
199
+ printf("%d件見つかりました\n", count);
200
+
201
+ }
202
+
203
+
204
+
205
+ void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
206
+
207
+ {
208
+
209
+ struct address *p;
210
+
211
+ if ((p = malloc(sizeof(struct address))) != 0) {
212
+
213
+
214
+
215
+ strcpy(p->name, name);
216
+
217
+
218
+
219
+ strcpy(p->address, address);
220
+
221
+ //文字型配列 p->address に文字列 address を '\0' までコピーします。
222
+
223
+
224
+
225
+ strcpy(p->tel, tel);
226
+
227
+ //文字型配列 p->number に文字列 number を '\0' までコピーします。
228
+
229
+
230
+
231
+ strcpy(p->mail, mail);
232
+
233
+ //文字型配列 p->mail に文字列 mail を '\0' までコピーします。
234
+
235
+
236
+
237
+ p->next = *head;
238
+
239
+ if (p->next != 0)
240
+
241
+ p->next->before = p;
242
+
243
+ p->before = 0;
244
+
245
+ *head = p;
246
+
247
+ }
248
+
249
+ }
250
+
251
+
252
+
253
+ void data_show(struct address *head) {
254
+
255
+ if (head != 0) {
256
+
257
+ printf(" %s, %s, %s, %s\n", head->name, head->address, head->tel, head->mail);
258
+
259
+ data_show(head->next);
260
+
261
+ }
262
+
263
+ }
60
264
 
61
265
 
62
266
 
@@ -74,6 +278,12 @@
74
278
 
75
279
  if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
76
280
 
281
+ // #include <string.h>
282
+
283
+ // int strcmp( const char *str1 , const char *str2 );
284
+
285
+ // str1<str2ならば負の値を返す。
286
+
77
287
  return head;
78
288
 
79
289
  else
@@ -84,94 +294,402 @@
84
294
 
85
295
 
86
296
 
87
- void exchange(struct address **p, struct address **q) {
297
+ void exchange(struct address **p, struct address **q)
298
+
88
-
299
+ {
300
+
89
- struct address *r, *s, *t;
301
+ struct address *r, *s, *t;
90
-
302
+
91
- assert(*p != 0 && *q != 0);
303
+ assert(*p != 0 && *q != 0);
304
+
305
+
306
+
307
+ if (p == q)
308
+
309
+ return;
310
+
311
+
312
+
313
+ r = *p; s = *q;
314
+
315
+ if (&((*p)->next) == q || &((*q)->next) == p) {
316
+
317
+ // (*p)はポインタで,(*p)->nextも次のポインタである。
318
+
319
+ // q(ポインタのポインタ)と(*p)->nextを比較するには&((*p)->next)とする。
320
+
321
+
322
+
323
+ if (s->next != 0){
324
+
325
+ // sと*qはおなじである。s->nextは(*q)->nextであるから
326
+
327
+ // (*q)->nextが0でないとき
328
+
329
+
330
+
331
+ s->next->before = r;
332
+
333
+ //(s->next)->beforeは((*q)->next)->beforeとおなじ
334
+
335
+ //rは*pと同じだから、(s->next)->beforeに*p(これはポインタ)を代入する。
336
+
337
+ }
338
+
339
+ r->before = s;
340
+
341
+ //rは*pであるから,*p->before = sである。s==*qなので
342
+
343
+ //*p->beforeに*q(これはポインタ)を代入する。
344
+
345
+
346
+
347
+ s->before = r->before;
348
+
349
+ // s->beforeに*q(これはポインタ)を代入する。
350
+
351
+ //
352
+
353
+
354
+
355
+ *p = s;
356
+
357
+ //sは*qだから*pに*q(これはポインタ)を代入する。
358
+
359
+
360
+
361
+ *q = s->next;
362
+
363
+ //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。
364
+
365
+
366
+
367
+ s->next = r;
368
+
369
+ //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。
370
+
371
+
372
+
373
+ return;
374
+
375
+ } else {
376
+
377
+ if (s->next != 0){
378
+
379
+ // (*q)->nextが0でないとき
380
+
381
+
382
+
383
+ s->next->before = r;
384
+
385
+ // (s->next)->before=*p
386
+
387
+ }
388
+
389
+ t = s->before;
390
+
391
+ // s->before==(*q)->before
392
+
393
+ // t=(*q)->before
394
+
395
+
396
+
397
+ s->before = r->before;
398
+
399
+ // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。
400
+
401
+
402
+
403
+ if (r->next != 0){
404
+
405
+ // (*p)->nextが0でないとき
406
+
407
+
408
+
409
+ r->next->before = s;
410
+
411
+ // (r->next)->before=*q
412
+
413
+ }
414
+
415
+ r->before = t;
416
+
417
+ // r->before==(*p)->before
418
+
419
+ // t=s->before
420
+
421
+ // r->beforeにs->before==(*q)->before(これはポインタ)を代入する。
422
+
423
+
424
+
425
+ t = r->next;
426
+
427
+ // r->next==(*p)->nextが0でないときであるから
428
+
429
+ // t=(*p)->next
430
+
431
+
432
+
433
+ r->next = s->next;
434
+
435
+ // s->next==(*q)->next
436
+
437
+ // r->next =(*q)->next
438
+
439
+
440
+
441
+ s->next = t;
442
+
443
+ // t=(*p)->next
444
+
445
+ // s->next=(*p)->next
446
+
447
+
448
+
449
+ *p = s;
450
+
451
+ *q = r;
452
+
453
+ }
454
+
455
+ }
456
+
457
+
458
+
459
+ void data_sort(struct address **head)
460
+
461
+ {
462
+
463
+ struct address **p;
464
+
465
+ if (*head != 0) {
466
+
467
+ for (;;) {
468
+
469
+ p = listmin(head);
470
+
471
+ if (p == 0)
472
+
473
+ break;
474
+
475
+
476
+
477
+ exchange(head, p);
478
+
479
+ head = &((*head)->next);
480
+
481
+ }
482
+
483
+ }
484
+
485
+ }
486
+
487
+
488
+
489
+ void release(struct address **head) {
490
+
491
+ if (*head != 0) {
492
+
493
+ release( &((*head)->next) );
494
+
495
+ free(*head);
496
+
497
+ *head = 0;
498
+
499
+ }
500
+
501
+ }
502
+
503
+
504
+
505
+ int main() {
506
+
507
+ struct address *head;
508
+
509
+ FILE* fp;
510
+
511
+ static char buff[N], name[N], address[N], tel[N], mail[N];
512
+
513
+ char *token=",";
514
+
515
+ int select;
92
516
 
93
517
 
94
518
 
95
- if (p == q)
96
-
97
- return;
98
-
99
- r = *p; s = *q;
100
-
101
- if (&((*p)->next) == q || &((*q)->next) == p) {
102
-
103
- if (s->next != 0)
104
-
105
- s->next->before = r;
106
-
107
- r->before = s;
108
-
109
- s->before = r->before;
110
-
111
- *p = s;
112
-
113
- *q = s->next;
114
-
115
- s->next = r;
116
-
117
- return;
118
-
119
- } else {
120
-
121
- if (s->next != 0)
122
-
123
- s->next->before = r;
124
-
125
- t = s->before;
126
-
127
- s->before = r->before;
128
-
129
- if (r->next != 0)
130
-
131
- r->next->before = s;
132
-
133
- r->before = t;
134
-
135
- /*-*/
136
-
137
- t = r->next;
138
-
139
- r->next = s->next;
140
-
141
- s->next = t;
142
-
143
- *p = s;
144
-
145
- *q = r;
519
+ head = 0;
520
+
521
+
522
+
523
+ if ((fp = fopen(FILENAME,"r")) != 0) {
524
+
525
+ while(fgets(buff, N, fp) != 0){
526
+
527
+ //本当の大元の文字列を書き換えないようにするために
528
+
529
+ //bufを確保してコピーし、それをstrtok()の引数にしている。
530
+
531
+ char *p;
532
+
533
+ chop(buff);
534
+
535
+ printf( "ファイルから読んだ文字列:%s\n", buff );
536
+
537
+
538
+
539
+ p = strtok(buff, token);
540
+
541
+ if ( p != NULL ) {
542
+
543
+ strcpy(name, p);
544
+
545
+ } else {
546
+
547
+ printf( "氏名の切り出しに失敗しました。\n");
548
+
549
+ break;
550
+
551
+ }
552
+
553
+
554
+
555
+ p = strtok(NULL, token);
556
+
557
+ if ( p != NULL ) {
558
+
559
+ strcpy(address, p);
560
+
561
+ } else {
562
+
563
+ printf( "住所の切り出しに失敗しました。\n");
564
+
565
+ break;
566
+
567
+ }
568
+
569
+
570
+
571
+ p = strtok(NULL, token);
572
+
573
+ if ( p != NULL ) {
574
+
575
+ strcpy(tel, p);
576
+
577
+ } else {
578
+
579
+ printf( "電話番号の切り出しに失敗しました。\n");
580
+
581
+ break;
582
+
583
+ }
584
+
585
+
586
+
587
+ p = strtok(NULL, token);
588
+
589
+ if ( p != NULL ) {
590
+
591
+ strcpy(mail, p);
592
+
593
+ } else {
594
+
595
+ printf( "メールアドレスの切り出しに失敗しました。\n");
596
+
597
+ break;
598
+
599
+ }
600
+
601
+ list_add(&head, name, address, tel, mail);
602
+
603
+ }
604
+
605
+ fclose(fp);
606
+
607
+ }
608
+
609
+ while(select != 0){
610
+
611
+ printf(" 1:ソ\ート 2:削除 3:追加 4:全体表\示 5:修正 6:検索 0:終了 \n");
612
+
613
+
614
+
615
+ printf("●メニューを入力して下さい ");
616
+
617
+ fgets(buff, N, stdin);
618
+
619
+
620
+
621
+ if (sscanf(buff, "%d", &select) != 1)
622
+
623
+
624
+
625
+ select = -1;
626
+
627
+
628
+
629
+ switch(select){
630
+
631
+ case 1:
632
+
633
+ data_sort(&head);
634
+
635
+ data_show(head);
636
+
637
+ break;
638
+
639
+    .....
640
+
641
+ 省略
642
+
643
+ .....
644
+
645
+
646
+
647
+
648
+
649
+ case 0:
650
+
651
+ printf("quit.\n");
652
+
653
+ break;
654
+
655
+ default:
656
+
657
+ printf("bad command, once more.\n");
658
+
659
+ break;
660
+
661
+ }
146
662
 
147
663
  }
148
664
 
665
+ release(&head);
666
+
667
+ return 0;
668
+
149
- }
669
+ }
150
-
151
-
152
-
670
+
671
+
672
+
153
- void data_sort(struct address **head) {
673
+ データ
154
-
674
+
155
- struct address **p;
675
+ address.csv
156
-
157
- if (*head != 0) {
676
+
158
-
159
- for (;;) {
160
-
161
- p = listmin(head);
677
+ yamada,tone,090-1122,mail-9
162
-
163
- if (p == 0)
678
+
164
-
165
- break;
166
-
167
- exchange(head, p);
679
+ hosi,nagoya,5436,mail-7
680
+
168
-
681
+ kato,kanagawa,080-8888,mail-2
682
+
683
+ koko,yosida,090-2314,mail-6
684
+
685
+ naka,kamikosaka,080-4444,mail-1
686
+
687
+ nakada,nogata,090-6376,mail-8
688
+
169
- head = &((*head)->next);
689
+ saito,yamanashi,080-6666,mail-3
170
-
690
+
171
- }
691
+ suzuki,saitama,090-2222,mail-5
172
-
173
- }
692
+
174
-
175
- }
693
+
176
694
 
177
695
  ```