質問編集履歴

18

コードの修正

2018/02/13 21:53

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -168,242 +168,220 @@
168
168
 
169
169
  r = *p; s = *q;
170
170
 
171
+ if (&((*p)->next) == q ) {
172
+
173
+ if (s->next != 0){
174
+
175
+ s->next->before = r;
176
+
177
+ }
178
+
179
+ s->before = r->before;
180
+
181
+ r->before = s;
182
+
183
+
184
+
185
+ *p = s;
186
+
187
+ *q = s->next;
188
+
189
+ s->next = r;
190
+
191
+
192
+
193
+ return;
194
+
195
+ }else{
196
+
171
- if (&((*p)->next) == q || &((*q)->next) == p) {
197
+ //(&((*p)->next) == q) && (&((*q)->next) == p)
172
-
173
- // &((*p)->next) == q において、**pはaddress構造体型ですから、
198
+
174
-
175
- //*pはaddress構造体へのポインタです。
199
+
176
-
177
- //従って、(*p)もaddress構造体へのポインタです。
200
+
178
-
179
- //であれば、(*p)->nextはaddress構造体のnextメンバですね。
180
-
181
- //ならば、&((*p)->next)はそのアドレスですから、
182
-
183
- //nextメンバのアドレスとなります。
184
-
185
- //それと q が等しいという条件ですから、qはadress構造体のnextメンバを
186
-
187
- //ポイントしているのだろうと思います。
188
-
189
- //つまり、*pが指すaddress構造体のnextメンバを
190
-
191
- //qがポイントしているならば、この条件が成立します。
192
-
193
-
194
-
195
- if (s->next != 0) s->next->before = r;
201
+ if (s->next != 0) s->next->before = r;
202
+
203
+ t = s->before;
204
+
205
+ s->before = r->before;
196
206
 
197
207
 
198
208
 
209
+ if (r->next != 0) r->next->before = s;
210
+
199
- r->before = s;
211
+ r->before = t;
212
+
213
+ t = r->next;
214
+
215
+ r->next = s->next;
216
+
217
+
218
+
219
+ s->next = t;
220
+
221
+
222
+
223
+ *p = s;
224
+
225
+ *q = r;
226
+
227
+ }
228
+
229
+ }
230
+
231
+
232
+
233
+ void data_sort(struct address **head) {
234
+
235
+ struct address **p;
236
+
237
+
238
+
239
+ if (*head != 0) {
240
+
241
+   for (;;) {
242
+
243
+ p = listmin(head);
244
+
245
+
246
+
247
+ if (p == 0)break;
248
+
249
+
250
+
251
+    exchange(head, p);
252
+
253
+
254
+
255
+
256
+
257
+ head = &((*head)->next);
258
+
259
+
260
+
261
+  exchange(head, p);
262
+
263
+  head = &((*head)->next);
264
+
265
+   }
266
+
267
+ }
268
+
269
+ }
270
+
271
+
272
+
273
+ void release(struct address **head)
274
+
275
+ {
276
+
277
+ if (*head != 0) {
278
+
279
+ release( &((*head)->next) );
280
+
281
+ free(*head);
282
+
283
+ *head = 0;
284
+
285
+ }
286
+
287
+ }
288
+
289
+
290
+
291
+ int main()
292
+
293
+ {
294
+
295
+ struct address *head;
296
+
297
+ FILE* fp;
298
+
299
+ static char buff[N], name[N], address[N], tel[N], mail[N];
300
+
301
+ char *token=",";
302
+
303
+
304
+
305
+ head = 0;
306
+
307
+
308
+
309
+ if ((fp = fopen(FILENAME,"r")) != 0) {
310
+
311
+ while(fgets(buff, N, fp) != 0){
312
+
313
+ //本当の大元の文字列を書き換えないようにするために
314
+
315
+ //bufを確保してコピーし、それをstrtok()の引数にしている。
316
+
317
+ char *p;
318
+
319
+ chop(buff);
320
+
321
+ printf( "ファイルから読んだ文字列:%s\n", buff );
200
322
 
201
323
 
202
324
 
203
- s->before = r->before;
325
+ p = strtok(buff, token);
326
+
327
+ if ( p != NULL ) {
328
+
329
+ strcpy(name, p);
330
+
331
+ } else {
332
+
333
+ printf( "氏名の切り出しに失敗しました。\n");
334
+
335
+ break;
336
+
337
+ }
338
+
339
+ p = strtok(NULL, token);
204
340
 
205
341
 
206
342
 
207
- *p = s;
208
-
209
- *q = s->next;
343
+ if ( p != NULL ) {
210
-
344
+
211
- s->next = r;
345
+ strcpy(address, p);
212
-
213
-
214
-
215
- return;
346
+
216
-
217
- }else{
347
+ } else {
218
-
219
- //(&((*p)->next) == q) && (&((*q)->next) == p)
348
+
220
-
221
-
222
-
223
- if (s->next != 0) s->next->before = r;
349
+ printf( "住所の切り出しに失敗しました。\n");
350
+
224
-
351
+ break;
352
+
353
+ }
354
+
225
- t = s->before;
355
+ p = strtok(NULL, token);
226
-
227
- s->before = r->before;
228
356
 
229
357
 
230
358
 
231
- if (r->next != 0) r->next->before = s;
232
-
233
- r->before = t;
234
-
235
- t = r->next;
359
+ if ( p != NULL ) {
236
-
237
- r->next = s->next;
360
+
238
-
239
-
240
-
241
- s->next = t;
361
+ strcpy(tel, p);
362
+
242
-
363
+ } else {
364
+
243
-
365
+ printf( "電話番号の切り出しに失敗しました。\n");
244
-
366
+
245
- *p = s;
367
+ break;
246
-
247
- *q = r;
368
+
248
-
249
- }
369
+ }
250
-
251
- }
370
+
252
-
253
-
254
-
255
- void data_sort(struct address **head) {
256
-
257
- struct address **p;
258
-
259
-
260
-
261
- if (*head != 0) {
262
-
263
-   for (;;) {
264
-
265
- p = listmin(head);
371
+ p = strtok(NULL, token);
266
-
267
-
268
-
269
- if (p == 0)break;
270
-
271
-
272
-
273
-    exchange(head, p);
274
-
275
-
276
-
277
-
278
-
279
- head = &((*head)->next);
280
-
281
-
282
-
283
-  exchange(head, p);
284
-
285
-  head = &((*head)->next);
286
-
287
-   }
288
-
289
- }
290
-
291
- }
292
-
293
-
294
-
295
- void release(struct address **head)
296
-
297
- {
298
-
299
- if (*head != 0) {
300
-
301
- release( &((*head)->next) );
302
-
303
- free(*head);
304
-
305
- *head = 0;
306
-
307
- }
308
-
309
- }
310
-
311
-
312
-
313
- int main()
314
-
315
- {
316
-
317
- struct address *head;
318
-
319
- FILE* fp;
320
-
321
- static char buff[N], name[N], address[N], tel[N], mail[N];
322
-
323
- char *token=",";
324
-
325
-
326
-
327
- head = 0;
328
-
329
-
330
-
331
- if ((fp = fopen(FILENAME,"r")) != 0) {
332
-
333
- while(fgets(buff, N, fp) != 0){
334
-
335
- //本当の大元の文字列を書き換えないようにするために
336
-
337
- //bufを確保してコピーし、それをstrtok()の引数にしている。
338
-
339
- char *p;
340
-
341
- chop(buff);
342
-
343
- printf( "ファイルから読んだ文字列:%s\n", buff );
344
372
 
345
373
 
346
374
 
347
- p = strtok(buff, token);
348
-
349
375
  if ( p != NULL ) {
350
376
 
351
- strcpy(name, p);
377
+ strcpy(mail, p);
352
378
 
353
379
  } else {
354
380
 
355
- printf( "氏名の切り出しに失敗しました。\n");
381
+ printf( "メールアドレスの切り出しに失敗しました。\n");
356
382
 
357
383
  break;
358
384
 
359
- }
360
-
361
- p = strtok(NULL, token);
362
-
363
-
364
-
365
- if ( p != NULL ) {
366
-
367
- strcpy(address, p);
368
-
369
- } else {
370
-
371
- printf( "住所の切り出しに失敗しました。\n");
372
-
373
- break;
374
-
375
- }
376
-
377
- p = strtok(NULL, token);
378
-
379
-
380
-
381
- if ( p != NULL ) {
382
-
383
- strcpy(tel, p);
384
-
385
- } else {
386
-
387
- printf( "電話番号の切り出しに失敗しました。\n");
388
-
389
- break;
390
-
391
- }
392
-
393
- p = strtok(NULL, token);
394
-
395
-
396
-
397
- if ( p != NULL ) {
398
-
399
- strcpy(mail, p);
400
-
401
- } else {
402
-
403
- printf( "メールアドレスの切り出しに失敗しました。\n");
404
-
405
- break;
406
-
407
385
  }
408
386
 
409
387
  list_add(&head, name, address, tel, mail);

17

図の変更

2018/02/13 21:53

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- ![イメージ説明](b8f599844e4193b93b3215291a124c95.jpeg)
5
+ ![イメージ説明](3690f5b239b8b85fac31d5fc77743308.jpeg)
6
6
 
7
7
  (*p)->next)はポインタpのnextでそのnextに入っている(*p)->next)のアドレスがポインタqのアドレス
8
8
 

16

図の修正

2018/02/13 00:42

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
 
4
4
 
5
- ![イメージ説明](18716b1ea96c3458f06ae0c5ccd79b08.jpeg)
5
+ ![イメージ説明](b8f599844e4193b93b3215291a124c95.jpeg)
6
-
6
+
7
- (*p)->next)はポインタpのnextでそのnextに入っているアドレスがポインタqのアドレス
7
+ (*p)->next)はポインタpのnextでそのnextに入っている(*p)->next)のアドレスがポインタqのアドレス
8
8
 
9
9
  と等しいということですよね。
10
10
 

15

図の修正

2018/02/11 05:46

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- ![イメージ説明](bd957b100c3b5d9ae99c1dcf4435296b.jpeg)
5
+ ![イメージ説明](18716b1ea96c3458f06ae0c5ccd79b08.jpeg)
6
6
 
7
7
  (*p)->next)はポインタpのnextでそのnextに入っているアドレスがポインタqのアドレス
8
8
 
@@ -154,176 +154,176 @@
154
154
 
155
155
  void exchange(struct address **p, struct address **q)
156
156
 
157
+ {![![イメージ説明](993302354d80fe7a9b8e9f78d293b8cc.jpeg)](b2aa359925707f49b302e1bc144a7110.jpeg)
158
+
159
+ struct address *r, *s, *t;
160
+
161
+ assert(*p != 0 && *q != 0);
162
+
163
+
164
+
165
+ if (p == q) return;
166
+
167
+
168
+
169
+ r = *p; s = *q;
170
+
171
+ if (&((*p)->next) == q || &((*q)->next) == p) {
172
+
173
+ // &((*p)->next) == q において、**pはaddress構造体型ですから、
174
+
175
+ //*pはaddress構造体へのポインタです。
176
+
177
+ //従って、(*p)もaddress構造体へのポインタです。
178
+
179
+ //であれば、(*p)->nextはaddress構造体のnextメンバですね。
180
+
181
+ //ならば、&((*p)->next)はそのアドレスですから、
182
+
183
+ //nextメンバのアドレスとなります。
184
+
185
+ //それと q が等しいという条件ですから、qはadress構造体のnextメンバを
186
+
187
+ //ポイントしているのだろうと思います。
188
+
189
+ //つまり、*pが指すaddress構造体のnextメンバを
190
+
191
+ //qがポイントしているならば、この条件が成立します。
192
+
193
+
194
+
195
+ if (s->next != 0) s->next->before = r;
196
+
197
+
198
+
199
+ r->before = s;
200
+
201
+
202
+
203
+ s->before = r->before;
204
+
205
+
206
+
207
+ *p = s;
208
+
209
+ *q = s->next;
210
+
211
+ s->next = r;
212
+
213
+
214
+
215
+ return;
216
+
217
+ }else{
218
+
219
+ //(&((*p)->next) == q) && (&((*q)->next) == p)
220
+
221
+
222
+
223
+ if (s->next != 0) s->next->before = r;
224
+
225
+ t = s->before;
226
+
227
+ s->before = r->before;
228
+
229
+
230
+
231
+ if (r->next != 0) r->next->before = s;
232
+
233
+ r->before = t;
234
+
235
+ t = r->next;
236
+
237
+ r->next = s->next;
238
+
239
+
240
+
241
+ s->next = t;
242
+
243
+
244
+
245
+ *p = s;
246
+
247
+ *q = r;
248
+
249
+ }
250
+
251
+ }
252
+
253
+
254
+
255
+ void data_sort(struct address **head) {
256
+
257
+ struct address **p;
258
+
259
+
260
+
261
+ if (*head != 0) {
262
+
263
+   for (;;) {
264
+
265
+ p = listmin(head);
266
+
267
+
268
+
269
+ if (p == 0)break;
270
+
271
+
272
+
273
+    exchange(head, p);
274
+
275
+
276
+
277
+
278
+
279
+ head = &((*head)->next);
280
+
281
+
282
+
283
+  exchange(head, p);
284
+
285
+  head = &((*head)->next);
286
+
287
+   }
288
+
289
+ }
290
+
291
+ }
292
+
293
+
294
+
295
+ void release(struct address **head)
296
+
157
297
  {
158
298
 
299
+ if (*head != 0) {
300
+
301
+ release( &((*head)->next) );
302
+
303
+ free(*head);
304
+
305
+ *head = 0;
306
+
307
+ }
308
+
309
+ }
310
+
311
+
312
+
313
+ int main()
314
+
315
+ {
316
+
159
- struct address *r, *s, *t;
317
+ struct address *head;
318
+
160
-
319
+ FILE* fp;
320
+
161
- assert(*p != 0 && *q != 0);
321
+ static char buff[N], name[N], address[N], tel[N], mail[N];
162
-
163
-
164
-
322
+
165
- if (p == q) return;
323
+ char *token=",";
166
324
 
167
325
 
168
326
 
169
- r = *p; s = *q;
170
-
171
- if (&((*p)->next) == q || &((*q)->next) == p) {
172
-
173
- // &((*p)->next) == q において、**pはaddress構造体型ですから、
174
-
175
- //*pはaddress構造体へのポインタです。
176
-
177
- //従って、(*p)もaddress構造体へのポインタです。
178
-
179
- //であれば、(*p)->nextはaddress構造体のnextメンバですね。
180
-
181
- //ならば、&((*p)->next)はそのアドレスですから、
182
-
183
- //nextメンバのアドレスとなります。
184
-
185
- //それと q が等しいという条件ですから、qはadress構造体のnextメンバを
186
-
187
- //ポイントしているのだろうと思います。
188
-
189
- //つまり、*pが指すaddress構造体のnextメンバを
190
-
191
- //qがポイントしているならば、この条件が成立します。
192
-
193
-
194
-
195
- if (s->next != 0) s->next->before = r;
196
-
197
-
198
-
199
- r->before = s;
200
-
201
-
202
-
203
- s->before = r->before;
204
-
205
-
206
-
207
- *p = s;
208
-
209
- *q = s->next;
210
-
211
- s->next = r;
212
-
213
-
214
-
215
- return;
216
-
217
- }else{
218
-
219
- //(&((*p)->next) == q) && (&((*q)->next) == p)
220
-
221
-
222
-
223
- if (s->next != 0) s->next->before = r;
224
-
225
- t = s->before;
226
-
227
- s->before = r->before;
228
-
229
-
230
-
231
- if (r->next != 0) r->next->before = s;
232
-
233
- r->before = t;
234
-
235
- t = r->next;
236
-
237
- r->next = s->next;
238
-
239
-
240
-
241
- s->next = t;
242
-
243
-
244
-
245
- *p = s;
246
-
247
- *q = r;
248
-
249
- }
250
-
251
- }
252
-
253
-
254
-
255
- void data_sort(struct address **head) {
256
-
257
- struct address **p;
258
-
259
-
260
-
261
- if (*head != 0) {
262
-
263
-   for (;;) {
264
-
265
- p = listmin(head);
266
-
267
-
268
-
269
- if (p == 0)break;
270
-
271
-
272
-
273
-    exchange(head, p);
274
-
275
-
276
-
277
-
278
-
279
- head = &((*head)->next);
280
-
281
-
282
-
283
-  exchange(head, p);
284
-
285
-  head = &((*head)->next);
286
-
287
-   }
288
-
289
- }
290
-
291
- }
292
-
293
-
294
-
295
- void release(struct address **head)
296
-
297
- {
298
-
299
- if (*head != 0) {
300
-
301
- release( &((*head)->next) );
302
-
303
- free(*head);
304
-
305
- *head = 0;
306
-
307
- }
308
-
309
- }
310
-
311
-
312
-
313
- int main()
314
-
315
- {
316
-
317
- struct address *head;
318
-
319
- FILE* fp;
320
-
321
- static char buff[N], name[N], address[N], tel[N], mail[N];
322
-
323
- char *token=",";
324
-
325
-
326
-
327
327
  head = 0;
328
328
 
329
329
 

14

質問の修正

2018/02/11 04:06

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,31 +1,19 @@
1
- void exchange() の中にif (&((*p)->next) == q || &((*q)->next) == p){}があります。
1
+ void exchange() の中にif (&((*p)->next) == q があります。
2
-
3
- 2件説明をもらいましたが、まったく逆の説明をもらいました。
2
+
4
-
5
- 2件のうちの1件は上図で、もう1件は矢印が逆のような説明でした。
3
+
6
-
7
- 図にしてみたんですが、ここの解釈を間違えると図にすると真逆になるので、
4
+
8
-
9
- 教えてください。
10
-
11
- ![イメージ説明](b2da630ef306bb50f5b731761d5f5deb.jpeg)
5
+ ![イメージ説明](bd957b100c3b5d9ae99c1dcf4435296b.jpeg)
12
-
13
-
14
-
6
+
15
- (*p)->next)はポインタpのnextでそのnext入っているアドレスが(ポインタのポインタ)q
7
+ (*p)->next)はポインタpのnextでそのnext入っているアドレスがポインタアドレス
16
8
 
17
9
  と等しいということですよね。
18
10
 
19
- 上図でいいでしょうか。(私はChilonianさんに説明して頂いた、このような感じでいいと思うのですが。)
11
+ 上図でいいでしょうか。
20
12
 
21
13
  よろしくお願いいたします。
22
14
 
23
15
 
24
16
 
25
- この後コードの中も図にしたいと思います。
26
-
27
-
28
-
29
17
  ```ここに言語を入力
30
18
 
31
19
  #include <stdlib.h>

13

修正

2018/02/11 01:51

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  教えてください。
10
10
 
11
- ![イメージ説明](1c7a6a2d7512a6ad2ff827d40a9605bc.jpeg)
11
+ ![イメージ説明](b2da630ef306bb50f5b731761d5f5deb.jpeg)
12
12
 
13
13
 
14
14
 
@@ -18,12 +18,6 @@
18
18
 
19
19
  上図でいいでしょうか。(私はChilonianさんに説明して頂いた、このような感じでいいと思うのですが。)
20
20
 
21
-
22
-
23
- それとも図で矢印を入れると下の図でいいのでしょうか。
24
-
25
- ![イメージ説明](70aaa2c196592e15ce8520fa896ddbd0.jpeg)
26
-
27
21
  よろしくお願いいたします。
28
22
 
29
23
 

12

質問の修正

2018/02/03 10:05

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -16,9 +16,11 @@
16
16
 
17
17
  と等しいということですよね。
18
18
 
19
-
19
+ 上図でいいでしょうか。(私はChilonianさんに説明して頂いた、このような感じでいいと思うのですが。)
20
-
20
+
21
+
22
+
21
- それ図で矢印を入れると下の図でいいのでしょうか。
23
+ それとも図で矢印を入れると下の図でいいのでしょうか。
22
24
 
23
25
  ![イメージ説明](70aaa2c196592e15ce8520fa896ddbd0.jpeg)
24
26
 

11

図の修正

2018/02/03 09:38

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  それに図で矢印を入れると下の図でいいのでしょうか。
22
22
 
23
- ![イメージ説明](687092a5c38524f1c5d68de5596214c6.jpeg)
23
+ ![イメージ説明](70aaa2c196592e15ce8520fa896ddbd0.jpeg)
24
24
 
25
25
  よろしくお願いいたします。
26
26
 

10

図の修正

2018/02/03 09:31

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  教えてください。
10
10
 
11
- ![イメージ説明](25f3c344da0997599868ef536b0c1d8e.jpeg)
11
+ ![イメージ説明](1c7a6a2d7512a6ad2ff827d40a9605bc.jpeg)
12
12
 
13
13
 
14
14
 

9

図の変更

2018/02/03 09:25

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  教えてください。
10
10
 
11
- ![イメージ説明](bc573b69e11e054e8597fbb226f5d457.jpeg)
11
+ ![イメージ説明](25f3c344da0997599868ef536b0c1d8e.jpeg)
12
12
 
13
13
 
14
14
 

8

図の変更

2018/02/03 08:43

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -8,9 +8,9 @@
8
8
 
9
9
  教えてください。
10
10
 
11
-
12
-
13
- ![イメージ説明](400b790346963a39e4ead4168b0e9bf8.jpeg)
11
+ ![イメージ説明](bc573b69e11e054e8597fbb226f5d457.jpeg)
12
+
13
+
14
14
 
15
15
  (*p)->next)はポインタpのnextでそのnextが入っているアドレスが(ポインタのポインタ)q
16
16
 

7

図の挿入

2018/02/03 08:15

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -2,11 +2,15 @@
2
2
 
3
3
  2件説明をもらいましたが、まったく逆の説明をもらいました。
4
4
 
5
+ 2件のうちの1件は上図で、もう1件は矢印が逆のような説明でした。
6
+
5
7
  図にしてみたんですが、ここの解釈を間違えると図にすると真逆になるので、
6
8
 
7
- 教えてください。図を載せるといいのですが、私は載せようとしたけど出来ないので、
8
-
9
- 以下で説明します
9
+ 教えてください
10
+
11
+
12
+
13
+ ![イメージ説明](400b790346963a39e4ead4168b0e9bf8.jpeg)
10
14
 
11
15
  (*p)->next)はポインタpのnextでそのnextが入っているアドレスが(ポインタのポインタ)q
12
16
 
@@ -14,16 +18,18 @@
14
18
 
15
19
 
16
20
 
17
- それに図で矢印を入れるときに (*p)->next->qでいいのでしょうか。
21
+ それに図で矢印を入れると下の図でいいのでしょうか。
18
-
19
- (わたしはこうではないかと思うのですが)
22
+
20
-
21
-
22
-
23
- それとも (*p)->next <-qでしょうか。
23
+ ![イメージ説明](687092a5c38524f1c5d68de5596214c6.jpeg)
24
24
 
25
25
  よろしくお願いいたします。
26
26
 
27
+
28
+
29
+ この後コードの中も図にしたいと思います。
30
+
31
+
32
+
27
33
  ```ここに言語を入力
28
34
 
29
35
  #include <stdlib.h>
@@ -180,7 +186,7 @@
180
186
 
181
187
  if (&((*p)->next) == q || &((*q)->next) == p) {
182
188
 
183
- // &((*p)->next) == q において、**pはaddress構造体型ですから、
189
+ // &((*p)->next) == q において、**pはaddress構造体型ですから、
184
190
 
185
191
  //*pはaddress構造体へのポインタです。
186
192
 

6

修正

2018/02/03 07:31

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -14,13 +14,13 @@
14
14
 
15
15
 
16
16
 
17
- それに図で矢印を入れるときに next->qでいいのでしょうか。
17
+ それに図で矢印を入れるときに (*p)->next->qでいいのでしょうか。
18
18
 
19
19
  (わたしはこうではないかと思うのですが)
20
20
 
21
21
 
22
22
 
23
- それとも next <-qでしょうか。
23
+ それとも (*p)->next <-qでしょうか。
24
24
 
25
25
  よろしくお願いいたします。
26
26
 

5

質問の修正

2018/01/31 10:03

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,6 @@
1
1
  void exchange() の中にif (&((*p)->next) == q || &((*q)->next) == p){}があります。
2
2
 
3
- 2件説明をもらいましたが、まったく逆の矢印の説明をもらいました。
3
+ 2件説明をもらいましたが、まったく逆の説明をもらいました。
4
4
 
5
5
  図にしてみたんですが、ここの解釈を間違えると図にすると真逆になるので、
6
6
 
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
 
17
- それに矢印を入れると next->qでいいのでしょうか。
17
+ それに図で矢印を入れるときに next->qでいいのでしょうか。
18
18
 
19
19
  (わたしはこうではないかと思うのですが)
20
20
 

4

コードの修正

2018/01/31 09:27

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -70,502 +70,366 @@
70
70
 
71
71
  ;
72
72
 
73
+ p--;
74
+
75
+
76
+
77
+ while (*p == '\r' || *p == '\n')
78
+
79
+ *(p--) = 0;
80
+
81
+ //
82
+
83
+ }
84
+
85
+ void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
86
+
87
+ {
88
+
89
+ struct address *p;
90
+
91
+ if ((p = malloc(sizeof(struct address))) != 0) {
92
+
93
+
94
+
95
+ strcpy(p->name, name);
96
+
97
+  strcpy(p->address, address);
98
+
99
+  strcpy(p->tel, tel);
100
+
101
+  strcpy(p->mail, mail);
102
+
103
+
104
+
105
+ p->next = *head;
106
+
107
+ if (p->next != 0)
108
+
109
+ p->next->before = p;
110
+
111
+ p->before = 0;
112
+
113
+ *head = p;
114
+
115
+ }
116
+
117
+ }
118
+
119
+
120
+
121
+ void data_show(struct address *head) {
122
+
123
+ if (head != 0) {
124
+
125
+ printf(" %s, %s, %s, %s\n", head->name, head->address, head->tel, head->mail);
126
+
127
+ data_show(head->next);
128
+
129
+ }
130
+
131
+ }
132
+
133
+
134
+
135
+ struct address **listmin(struct address **head) {
136
+
137
+ struct address **p;
138
+
139
+
140
+
141
+ if (*head == 0)
142
+
143
+ return 0;
144
+
145
+ if ((*head)->next == 0)
146
+
147
+ return head;
148
+
149
+ //
150
+
151
+
152
+
153
+ if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
154
+
155
+ return head;
156
+
157
+ else
158
+
159
+ return p;
160
+
161
+ }
162
+
163
+
164
+
165
+ void exchange(struct address **p, struct address **q)
166
+
167
+ {
168
+
169
+ struct address *r, *s, *t;
170
+
171
+ assert(*p != 0 && *q != 0);
172
+
173
+
174
+
175
+ if (p == q) return;
176
+
73
177
 
74
178
 
75
- //まず、char *p に対して、for(s = p; *p; p++) に現れる、
76
-
77
- //*p の型は(ポインタではなく)char そのものです。
78
-
79
- //ですから、*p p がポイントしているところにある char のデータ」です
80
-
81
-
82
-
83
- //一方は、文字列は、「'\0' で終端される」という規定になっています。
84
-
85
- //ですから、ちょっとくどく書けば、
86
-
87
- //for(s = p; *p != '\0' ; p++)ということ,
88
-
89
- //「p がポイトする文字が、終端文字(文字列終わ)にくるで」
90
-
91
- //という意味です
92
-
93
-
94
-
95
- //そして(Cのいろいろな背景から) *p != '\0' という表記は、
96
-
97
- //*p とだけ書た時と同じ動作をします。
98
-
99
- //このため、文字列の終端をチェックするために、while(*p) とか、
100
-
101
- //if(! *p) こっちは、終端にきたときの判断)とかよく使われる表現です。
102
-
103
-
104
-
105
- //なお、NULL は、「何もポイントしていないポインタ」の値です。
106
-
107
- //そして、ちょっと面倒なのが、規格上は、
108
-
109
- //「ヌルポインタ(何もポイントしていないポインタ)の値は、
110
-
111
- //定数0と比較したときに等しくなる」と定義されている点です。
112
-
113
-
114
-
115
- p--; // *pが\0となりfor()を抜けるとここに来る。
116
-
117
- //ポインタを1個戻して,\0 の前が'\r'か'\n'どうか調べるため。
118
-
119
-
120
-
121
- while (*p == '\r' || *p == '\n')
122
-
123
- *(p--) = 0;
124
-
125
- //
126
-
127
- }//chop()を抜けると\0で区切られた文字列になる。
128
-
129
-
130
-
131
- void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
179
+ r = *p; s = *q;
180
+
181
+ if (&((*p)->next) == q || &((*q)->next) == p) {
182
+
183
+ // &((*p)->next) == q において**paddress構造体型ですから、
184
+
185
+ //*pはaddress構造体へのポインタです。
186
+
187
+ //従って(*p)もaddress構造体へのポインタです。
188
+
189
+ //であれば、(*p)->nextはaddress構造体のnextメンバですね。
190
+
191
+ //ならば、&((*p)->next)はそのアドレスすから、
192
+
193
+ //nextメアドレスとなります。
194
+
195
+ //それ q が等しとい条件ですから、qはadress構造体のnextメンバを
196
+
197
+ //ポイントしているのだろうと思います。
198
+
199
+ //つまり、*pが指すaddress構造体のnextメンバを
200
+
201
+ //qがポイントしてるならば、この条件が成立します。
202
+
203
+
204
+
205
+ if (s->next != 0) s->next->before = r;
206
+
207
+
208
+
209
+ r->before = s;
210
+
211
+
212
+
213
+ s->before = r->before;
214
+
215
+
216
+
217
+ *p = s;
218
+
219
+ *q = s->next;
220
+
221
+ s->next = r;
222
+
223
+
224
+
225
+ return;
226
+
227
+ }else{
228
+
229
+ //(&((*p)->next) == q) && (&((*q)->next) == p)
230
+
231
+
232
+
233
+ if (s->next != 0) s->next->before = r;
234
+
235
+ t = s->before;
236
+
237
+ s->before = r->before;
238
+
239
+
240
+
241
+ if (r->next != 0) r->next->before = s;
242
+
243
+ r->before = t;
244
+
245
+ t = r->next;
246
+
247
+ r->next = s->next;
248
+
249
+
250
+
251
+ s->next = t;
252
+
253
+
254
+
255
+ *p = s;
256
+
257
+ *q = r;
258
+
259
+ }
260
+
261
+ }
262
+
263
+
264
+
265
+ void data_sort(struct address **head) {
266
+
267
+ struct address **p;
268
+
269
+
270
+
271
+ if (*head != 0) {
272
+
273
+   for (;;) {
274
+
275
+ p = listmin(head);
276
+
277
+
278
+
279
+ if (p == 0)break;
280
+
281
+
282
+
283
+    exchange(head, p);
284
+
285
+
286
+
287
+
288
+
289
+ head = &((*head)->next);
290
+
291
+
292
+
293
+  exchange(head, p);
294
+
295
+  head = &((*head)->next);
296
+
297
+   }
298
+
299
+ }
300
+
301
+ }
302
+
303
+
304
+
305
+ void release(struct address **head)
132
306
 
133
307
  {
134
308
 
309
+ if (*head != 0) {
310
+
311
+ release( &((*head)->next) );
312
+
313
+ free(*head);
314
+
315
+ *head = 0;
316
+
317
+ }
318
+
319
+ }
320
+
321
+
322
+
323
+ int main()
324
+
325
+ {
326
+
135
- struct address *p;
327
+ struct address *head;
328
+
136
-
329
+ FILE* fp;
330
+
137
- if ((p = malloc(sizeof(struct address))) != 0) {
331
+ static char buff[N], name[N], address[N], tel[N], mail[N];
332
+
333
+ char *token=",";
334
+
335
+
336
+
337
+ head = 0;
138
338
 
139
339
 
140
340
 
141
- strcpy(p->name, name);
142
-
143
- //文字列のコピー
144
-
145
- //式】
146
-
147
- //#include <string.h>
148
-
149
- //char *strcpy(char *s1, const char *s2);
150
-
151
-
152
-
153
- //【説明】
154
-
155
- //文字型配列 *s1 に文字列 *s2 を '\0' までコピーします。
156
-
157
- //'\0' もコピーするので s1 はその分も考えて大きさを宣言して
158
-
159
- //おかなければなりません。
160
-
161
- //もし、s1 と s2 が重なっている場合には動作は未定義となります。
162
-
163
-
164
-
165
- strcpy(p->address, address);
166
-
167
- //文字型配列 p->address に文字列 address を '\0' までコピーします。
168
-
169
-
170
-
171
- strcpy(p->tel, tel);
172
-
173
- //文字型配列 p->number に文字列 number を '\0' までコピーします。
174
-
175
-
176
-
177
- strcpy(p->mail, mail);
178
-
179
- //文字型配列 p->mail に文字列 mail を '\0' までコピーします。
180
-
181
-
182
-
183
- p->next = *head;
184
-
185
- if (p->next != 0)
186
-
187
- p->next->before = p;
188
-
189
- p->before = 0;
190
-
191
- *head = p;
192
-
193
- }
194
-
195
- }
196
-
197
-
198
-
199
- void data_show(struct address *head) {
200
-
201
- if (head != 0) {
202
-
203
- printf(" %s, %s, %s, %s\n", head->name, head->address, head->tel, head->mail);
204
-
205
- data_show(head->next);
206
-
207
- }
208
-
209
- }
210
-
211
-
212
-
213
- struct address **listmin(struct address **head) {
214
-
215
- struct address **p;
216
-
217
-
218
-
219
- if (*head == 0)
220
-
221
- return 0;
222
-
223
- if ((*head)->next == 0)
224
-
225
- return head;
226
-
227
- //
228
-
229
-
230
-
231
- if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
232
-
233
- return head;
234
-
235
- else
236
-
237
- return p;
238
-
239
- }
240
-
241
-
242
-
243
- //リストheadから要素pを引っこ抜いて、抜けた部分を繋ぎ直す。
244
-
245
- //リストheadの先頭に要素pを追加して、要素pを新しいリストの先頭にする。
246
-
247
- //大小を入れ替える
248
-
249
- void exchange(struct address **p, struct address **q)
250
-
251
- {
252
-
253
- struct address *r, *s, *t;
254
-
255
- assert(*p != 0 && *q != 0);
256
-
257
-
258
-
259
- if (p == q) return;
260
-
261
-
262
-
263
- r = *p; s = *q;
264
-
265
- if (&((*p)->next) == q || &((*q)->next) == p) {
266
-
267
- // &((*p)->next) == q において、**pはaddress構造体型ですから、
268
-
269
- //*pはaddress構造体へのポインタです。
270
-
271
-
272
-
273
- //従って、(*p)もaddress構造体へのポインタです。
341
+ if ((fp = fopen(FILENAME,"r")) != 0) {
342
+
343
+ while(fgets(buff, N, fp) != 0){
344
+
345
+ //本当の大元の文字列をき換えないようにするために
346
+
347
+ //bufを確保してコピーし、それをstrtok()の引数にしている。
348
+
349
+ char *p;
350
+
351
+ chop(buff);
352
+
353
+ printf( "ファイルから読んだ文字列:%s\n", buff );
354
+
355
+
356
+
357
+ p = strtok(buff, token);
358
+
359
+ if ( p != NULL ) {
360
+
361
+ strcpy(name, p);
362
+
363
+ } else {
364
+
365
+ printf( "氏名の切り出しに失敗しました。\n");
366
+
367
+ break;
368
+
369
+ }
370
+
371
+ p = strtok(NULL, token);
372
+
373
+
374
+
375
+ if ( p != NULL ) {
376
+
377
+ strcpy(address, p);
378
+
379
+ } else {
380
+
381
+ printf( "住所の切り出しに失敗しました。\n");
382
+
383
+ break;
384
+
385
+ }
386
+
387
+ p = strtok(NULL, token);
388
+
389
+
390
+
391
+ if ( p != NULL ) {
392
+
393
+ strcpy(tel, p);
394
+
395
+ } else {
396
+
397
+ printf( "電話番号の切り出しに失敗しました。\n");
398
+
399
+ break;
400
+
401
+ }
402
+
403
+ p = strtok(NULL, token);
404
+
405
+
406
+
407
+ if ( p != NULL ) {
408
+
409
+ strcpy(mail, p);
410
+
411
+ } else {
412
+
413
+ printf( "メールアドレスの切り出しに失敗しました。\n");
414
+
415
+ break;
416
+
417
+ }
418
+
419
+ list_add(&head, name, address, tel, mail);
420
+
421
+ }
422
+
423
+ fclose(fp);
424
+
425
+ }
426
+
427
+ data_sort(&head);
428
+
429
+ data_show(head);
274
430
 
275
431
 
276
432
 
277
- //であれば、(*p)->nextはaddress構造体のnextメンバですね。
278
-
279
-
280
-
281
- //ならば、&((*p)->next)はそのアドレスですから、
282
-
283
- //nextメンバのアドレスとなります。
284
-
285
-
286
-
287
- //それと q が等しいという条件ですから、qはadress構造体のnextメンバを
288
-
289
- //ポイントしているのだろうと思います。
290
-
291
-
292
-
293
- //つまり、*pが指すaddress構造体のnextメンバを
294
-
295
- //qがポイントしているならば、この条件が成立します。
296
-
297
-
298
-
299
- //&((*q)->next) == pにおいて、**qはaddress構造体型ですから、
300
-
301
- //*qはaddress構造体へのポインタです。
302
-
303
-
304
-
305
- //従って、(*q)もaddress構造体へのポインタです。
306
-
307
-
308
-
309
- //であれば、(*q)->nextはaddress構造体のnextメンバですね。
310
-
311
-
312
-
313
- //ならば、&((*q)->next)はそのアドレスですから、
314
-
315
- //nextメンバのアドレスとなります。
316
-
317
-
318
-
319
- //それと p が等しいという条件ですから、pはadress構造体のnextメンバを
320
-
321
- //ポイントしているのだろうと思います。
322
-
323
-
324
-
325
- //つまり、*qが指すaddress構造体のnextメンバを
326
-
327
- //pがポイントしているならば、この条件が成立します。
328
-
329
-
330
-
331
- if (s->next != 0) s->next->before = r;
332
-
333
-
334
-
335
- r->before = s;
336
-
337
-
338
-
339
- s->before = r->before;
340
-
341
-
342
-
343
- *p = s;
344
-
345
- *q = s->next;
346
-
347
-
348
-
349
-
350
-
351
- s->next = r;
352
-
353
-
354
-
355
- return;
356
-
357
- }else{
358
-
359
- //(&((*p)->next) == q) && (&((*q)->next) == p)
360
-
361
-
362
-
363
- if (s->next != 0) s->next->before = r;
364
-
365
-
366
-
367
-     t = s->before;
368
-
369
-
370
-
371
- s->before = r->before;
372
-
373
-
374
-
375
- if (r->next != 0) r->next->before = s;
376
-
377
- r->before = t;
378
-
379
- t = r->next;
380
-
381
-
382
-
383
- r->next = s->next;
384
-
385
-
386
-
387
- s->next = t;
388
-
389
-
390
-
391
- *p = s;
392
-
393
- *q = r;
394
-
395
- }
396
-
397
- }
398
-
399
-
400
-
401
- void data_sort(struct address **head) {
402
-
403
- struct address **p;
404
-
405
-
406
-
407
- if (*head != 0) {
408
-
409
-   for (;;) {
410
-
411
- p = listmin(head);
412
-
413
-
414
-
415
- if (p == 0)break;
416
-
417
-
418
-
419
-    exchange(head, p);
420
-
421
-
422
-
423
-
424
-
425
- head = &((*head)->next);
426
-
427
-
428
-
429
-  exchange(head, p);
430
-
431
-  head = &((*head)->next);
432
-
433
-   }
434
-
435
- }
436
-
437
- }
438
-
439
-
440
-
441
- void release(struct address **head)
442
-
443
- {
444
-
445
- if (*head != 0) {
446
-
447
- release( &((*head)->next) );
448
-
449
- free(*head);
450
-
451
- *head = 0;
452
-
453
- }
454
-
455
- }
456
-
457
-
458
-
459
- int main()
460
-
461
- {
462
-
463
- struct address *head;
464
-
465
- FILE* fp;
466
-
467
- static char buff[N], name[N], address[N], tel[N], mail[N];
468
-
469
- char *token=",";
470
-
471
-
472
-
473
- head = 0;
474
-
475
-
476
-
477
- if ((fp = fopen(FILENAME,"r")) != 0) {
478
-
479
- while(fgets(buff, N, fp) != 0){
480
-
481
- //本当の大元の文字列を書き換えないようにするために
482
-
483
- //bufを確保してコピーし、それをstrtok()の引数にしている。
484
-
485
- char *p;
486
-
487
- chop(buff);
488
-
489
- printf( "ファイルから読んだ文字列:%s\n", buff );
490
-
491
-
492
-
493
- p = strtok(buff, token);
494
-
495
- if ( p != NULL ) {
496
-
497
- strcpy(name, p);
498
-
499
- } else {
500
-
501
- printf( "氏名の切り出しに失敗しました。\n");
502
-
503
- break;
504
-
505
- }
506
-
507
- p = strtok(NULL, token);
508
-
509
-
510
-
511
- if ( p != NULL ) {
512
-
513
- strcpy(address, p);
514
-
515
- } else {
516
-
517
- printf( "住所の切り出しに失敗しました。\n");
518
-
519
- break;
520
-
521
- }
522
-
523
- p = strtok(NULL, token);
524
-
525
-
526
-
527
- if ( p != NULL ) {
528
-
529
- strcpy(tel, p);
530
-
531
- } else {
532
-
533
- printf( "電話番号の切り出しに失敗しました。\n");
534
-
535
- break;
536
-
537
- }
538
-
539
- p = strtok(NULL, token);
540
-
541
-
542
-
543
- if ( p != NULL ) {
544
-
545
- strcpy(mail, p);
546
-
547
- } else {
548
-
549
- printf( "メールアドレスの切り出しに失敗しました。\n");
550
-
551
- break;
552
-
553
- }
554
-
555
- list_add(&head, name, address, tel, mail);
556
-
557
- }
558
-
559
- fclose(fp);
560
-
561
- }
562
-
563
- data_sort(&head);
564
-
565
- data_show(head);
566
-
567
-
568
-
569
433
  release(&head);
570
434
 
571
435
  return 0;

3

こーどしゅうせい

2018/01/31 09:16

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,4 +1,4 @@
1
- コードの中にif (&((*p)->next) == q || &((*q)->next) == p){}があります。
1
+ void exchange() の中にif (&((*p)->next) == q || &((*q)->next) == p){}があります。
2
2
 
3
3
  2件説明をもらいましたが、まったく逆の矢印の説明をもらいました。
4
4
 

2

コードの追加

2018/01/31 08:42

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -26,7 +26,19 @@
26
26
 
27
27
  ```ここに言語を入力
28
28
 
29
+ #include <stdlib.h>
30
+
31
+ #include <string.h>
32
+
33
+ #include <assert.h> //
34
+
35
+
36
+
29
- コード
37
+ #define N 256
38
+
39
+ #define FILENAME "address.csv"
40
+
41
+
30
42
 
31
43
  struct address{
32
44
 
@@ -44,4 +56,522 @@
44
56
 
45
57
  };
46
58
 
59
+
60
+
61
+ void data_show(struct address* head);
62
+
63
+ void data_sort(struct address** head);
64
+
65
+
66
+
67
+ void chop(char *p){
68
+
69
+ for (; *p; p++)
70
+
71
+ ;
72
+
73
+
74
+
75
+ //まず、char *p に対して、for(s = p; *p; p++) に現れる、
76
+
77
+ //*p の型は(ポインタではなく)char そのものです。
78
+
79
+ //ですから、*p は、「p がポイントしているところにある char のデータ」です。
80
+
81
+
82
+
83
+ //一方、Cでは、文字列は、「'\0' で終端される」という規定になっています。
84
+
85
+ //ですから、ちょっとくどく書けば、
86
+
87
+ //for(s = p; *p != '\0' ; p++)ということで,
88
+
89
+ //「p がポイントする文字が、終端文字(文字列の終わり)にくるまで」
90
+
91
+ //という意味です。
92
+
93
+
94
+
95
+ //そして、(Cのいろいろな背景から) *p != '\0' という表記は、
96
+
97
+ //*p とだけ書いた時と同じ動作をします。
98
+
99
+ //このため、文字列の終端をチェックするために、while(*p) とか、
100
+
101
+ //if(! *p) こっちは、終端にきたときの判断)とかよく使われる表現です。
102
+
103
+
104
+
105
+ //なお、NULL は、「何もポイントしていないポインタ」の値です。
106
+
107
+ //そして、ちょっと面倒なのが、規格上は、
108
+
109
+ //「ヌルポインタ(何もポイントしていないポインタ)の値は、
110
+
111
+ //定数0と比較したときに等しくなる」と定義されている点です。
112
+
113
+
114
+
115
+ p--; // *pが\0となりfor()を抜けるとここに来る。
116
+
117
+ //ポインタを1個戻して,\0 の前が'\r'か'\n'どうか調べるため。
118
+
119
+
120
+
121
+ while (*p == '\r' || *p == '\n')
122
+
123
+ *(p--) = 0;
124
+
125
+ //
126
+
127
+ }//chop()を抜けると\0で区切られた文字列になる。
128
+
129
+
130
+
131
+ void list_add(struct address **head, char *name, char *address, char *tel, char *mail)
132
+
133
+ {
134
+
135
+ struct address *p;
136
+
137
+ if ((p = malloc(sizeof(struct address))) != 0) {
138
+
139
+
140
+
141
+ strcpy(p->name, name);
142
+
143
+ //文字列のコピー
144
+
145
+ //【書式】
146
+
147
+ //#include <string.h>
148
+
149
+ //char *strcpy(char *s1, const char *s2);
150
+
151
+
152
+
153
+ //【説明】
154
+
155
+ //文字型配列 *s1 に文字列 *s2 を '\0' までコピーします。
156
+
157
+ //'\0' もコピーするので s1 はその分も考えて大きさを宣言して
158
+
159
+ //おかなければなりません。
160
+
161
+ //もし、s1 と s2 が重なっている場合には動作は未定義となります。
162
+
163
+
164
+
165
+ strcpy(p->address, address);
166
+
167
+ //文字型配列 p->address に文字列 address を '\0' までコピーします。
168
+
169
+
170
+
171
+ strcpy(p->tel, tel);
172
+
173
+ //文字型配列 p->number に文字列 number を '\0' までコピーします。
174
+
175
+
176
+
177
+ strcpy(p->mail, mail);
178
+
179
+ //文字型配列 p->mail に文字列 mail を '\0' までコピーします。
180
+
181
+
182
+
183
+ p->next = *head;
184
+
185
+ if (p->next != 0)
186
+
187
+ p->next->before = p;
188
+
189
+ p->before = 0;
190
+
191
+ *head = p;
192
+
193
+ }
194
+
195
+ }
196
+
197
+
198
+
199
+ void data_show(struct address *head) {
200
+
201
+ if (head != 0) {
202
+
203
+ printf(" %s, %s, %s, %s\n", head->name, head->address, head->tel, head->mail);
204
+
205
+ data_show(head->next);
206
+
207
+ }
208
+
209
+ }
210
+
211
+
212
+
213
+ struct address **listmin(struct address **head) {
214
+
215
+ struct address **p;
216
+
217
+
218
+
219
+ if (*head == 0)
220
+
221
+ return 0;
222
+
223
+ if ((*head)->next == 0)
224
+
225
+ return head;
226
+
227
+ //
228
+
229
+
230
+
231
+ if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0)
232
+
233
+ return head;
234
+
235
+ else
236
+
237
+ return p;
238
+
239
+ }
240
+
241
+
242
+
243
+ //リストheadから要素pを引っこ抜いて、抜けた部分を繋ぎ直す。
244
+
245
+ //リストheadの先頭に要素pを追加して、要素pを新しいリストの先頭にする。
246
+
247
+ //大小を入れ替える
248
+
249
+ void exchange(struct address **p, struct address **q)
250
+
251
+ {
252
+
253
+ struct address *r, *s, *t;
254
+
255
+ assert(*p != 0 && *q != 0);
256
+
257
+
258
+
259
+ if (p == q) return;
260
+
261
+
262
+
263
+ r = *p; s = *q;
264
+
265
+ if (&((*p)->next) == q || &((*q)->next) == p) {
266
+
267
+ // &((*p)->next) == q において、**pはaddress構造体型ですから、
268
+
269
+ //*pはaddress構造体へのポインタです。
270
+
271
+
272
+
273
+ //従って、(*p)もaddress構造体へのポインタです。
274
+
275
+
276
+
277
+ //であれば、(*p)->nextはaddress構造体のnextメンバですね。
278
+
279
+
280
+
281
+ //ならば、&((*p)->next)はそのアドレスですから、
282
+
283
+ //nextメンバのアドレスとなります。
284
+
285
+
286
+
287
+ //それと q が等しいという条件ですから、qはadress構造体のnextメンバを
288
+
289
+ //ポイントしているのだろうと思います。
290
+
291
+
292
+
293
+ //つまり、*pが指すaddress構造体のnextメンバを
294
+
295
+ //qがポイントしているならば、この条件が成立します。
296
+
297
+
298
+
299
+ //&((*q)->next) == pにおいて、**qはaddress構造体型ですから、
300
+
301
+ //*qはaddress構造体へのポインタです。
302
+
303
+
304
+
305
+ //従って、(*q)もaddress構造体へのポインタです。
306
+
307
+
308
+
309
+ //であれば、(*q)->nextはaddress構造体のnextメンバですね。
310
+
311
+
312
+
313
+ //ならば、&((*q)->next)はそのアドレスですから、
314
+
315
+ //nextメンバのアドレスとなります。
316
+
317
+
318
+
319
+ //それと p が等しいという条件ですから、pはadress構造体のnextメンバを
320
+
321
+ //ポイントしているのだろうと思います。
322
+
323
+
324
+
325
+ //つまり、*qが指すaddress構造体のnextメンバを
326
+
327
+ //pがポイントしているならば、この条件が成立します。
328
+
329
+
330
+
331
+ if (s->next != 0) s->next->before = r;
332
+
333
+
334
+
335
+ r->before = s;
336
+
337
+
338
+
339
+ s->before = r->before;
340
+
341
+
342
+
343
+ *p = s;
344
+
345
+ *q = s->next;
346
+
347
+
348
+
349
+
350
+
351
+ s->next = r;
352
+
353
+
354
+
355
+ return;
356
+
357
+ }else{
358
+
359
+ //(&((*p)->next) == q) && (&((*q)->next) == p)
360
+
361
+
362
+
363
+ if (s->next != 0) s->next->before = r;
364
+
365
+
366
+
367
+     t = s->before;
368
+
369
+
370
+
371
+ s->before = r->before;
372
+
373
+
374
+
375
+ if (r->next != 0) r->next->before = s;
376
+
377
+ r->before = t;
378
+
379
+ t = r->next;
380
+
381
+
382
+
383
+ r->next = s->next;
384
+
385
+
386
+
387
+ s->next = t;
388
+
389
+
390
+
391
+ *p = s;
392
+
393
+ *q = r;
394
+
395
+ }
396
+
397
+ }
398
+
399
+
400
+
401
+ void data_sort(struct address **head) {
402
+
403
+ struct address **p;
404
+
405
+
406
+
407
+ if (*head != 0) {
408
+
409
+   for (;;) {
410
+
411
+ p = listmin(head);
412
+
413
+
414
+
415
+ if (p == 0)break;
416
+
417
+
418
+
419
+    exchange(head, p);
420
+
421
+
422
+
423
+
424
+
425
+ head = &((*head)->next);
426
+
427
+
428
+
429
+  exchange(head, p);
430
+
431
+  head = &((*head)->next);
432
+
433
+   }
434
+
435
+ }
436
+
437
+ }
438
+
439
+
440
+
441
+ void release(struct address **head)
442
+
443
+ {
444
+
445
+ if (*head != 0) {
446
+
447
+ release( &((*head)->next) );
448
+
449
+ free(*head);
450
+
451
+ *head = 0;
452
+
453
+ }
454
+
455
+ }
456
+
457
+
458
+
459
+ int main()
460
+
461
+ {
462
+
463
+ struct address *head;
464
+
465
+ FILE* fp;
466
+
467
+ static char buff[N], name[N], address[N], tel[N], mail[N];
468
+
469
+ char *token=",";
470
+
471
+
472
+
473
+ head = 0;
474
+
475
+
476
+
477
+ if ((fp = fopen(FILENAME,"r")) != 0) {
478
+
479
+ while(fgets(buff, N, fp) != 0){
480
+
481
+ //本当の大元の文字列を書き換えないようにするために
482
+
483
+ //bufを確保してコピーし、それをstrtok()の引数にしている。
484
+
485
+ char *p;
486
+
487
+ chop(buff);
488
+
489
+ printf( "ファイルから読んだ文字列:%s\n", buff );
490
+
491
+
492
+
493
+ p = strtok(buff, token);
494
+
495
+ if ( p != NULL ) {
496
+
497
+ strcpy(name, p);
498
+
499
+ } else {
500
+
501
+ printf( "氏名の切り出しに失敗しました。\n");
502
+
503
+ break;
504
+
505
+ }
506
+
507
+ p = strtok(NULL, token);
508
+
509
+
510
+
511
+ if ( p != NULL ) {
512
+
513
+ strcpy(address, p);
514
+
515
+ } else {
516
+
517
+ printf( "住所の切り出しに失敗しました。\n");
518
+
519
+ break;
520
+
521
+ }
522
+
523
+ p = strtok(NULL, token);
524
+
525
+
526
+
527
+ if ( p != NULL ) {
528
+
529
+ strcpy(tel, p);
530
+
531
+ } else {
532
+
533
+ printf( "電話番号の切り出しに失敗しました。\n");
534
+
535
+ break;
536
+
537
+ }
538
+
539
+ p = strtok(NULL, token);
540
+
541
+
542
+
543
+ if ( p != NULL ) {
544
+
545
+ strcpy(mail, p);
546
+
547
+ } else {
548
+
549
+ printf( "メールアドレスの切り出しに失敗しました。\n");
550
+
551
+ break;
552
+
553
+ }
554
+
555
+ list_add(&head, name, address, tel, mail);
556
+
557
+ }
558
+
559
+ fclose(fp);
560
+
561
+ }
562
+
563
+ data_sort(&head);
564
+
565
+ data_show(head);
566
+
567
+
568
+
569
+ release(&head);
570
+
571
+ return 0;
572
+
573
+ }
574
+
575
+
576
+
47
577
  ```

1

コードの追加

2018/01/31 08:40

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -23,3 +23,25 @@
23
23
  それとも next <-qでしょうか。
24
24
 
25
25
  よろしくお願いいたします。
26
+
27
+ ```ここに言語を入力
28
+
29
+ コード
30
+
31
+ struct address{
32
+
33
+ char name[N];
34
+
35
+ char address[N];
36
+
37
+ char tel[N]; // 電話番号
38
+
39
+ char mail[N];
40
+
41
+ struct address *next;
42
+
43
+ struct address *before;
44
+
45
+ };
46
+
47
+ ```