質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

1899閲覧

リスト構造体 追加 削除

ksyiwk

総合スコア24

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/12/16 06:44

編集2022/01/12 10:55

C言語で、以下のプログラムを元にして、データ入力後に任意の場所にデータを追加や削除するプログラムをリスト構造を用いて作成したいのですが、どなたか教えてください。 また、データ追加後や削除後の番号も正しく表示させたいです。データの追加と削除のプログラムははそれぞれ別のソースコードで表します。

#include<stdio.h> struct Data{ int No; char Name[20]; double Height; double Weight; struct Data *next; }d[10]; int main(){ struct Data *p,*temp; int i,a; p=&d[0]; printf("Please input the number of people:"); scanf("%d",&a); for(i=0;i<a;i++){ printf("No,%d name : ",i+1); d[i].No=i+1; scanf("%s",d[i].Name); printf("height : "); scanf("%lf",&d[i].Height); printf("weight : "); scanf("%lf",&d[i].Weight); if(i==a-1){ d[i].next = NULL; }else{ d[i].next = &d[i+1]; } } p=&d[0]; while(p!=NULL){ printf("No,%d : %s\n",p->No,p->Name); printf("%.1f[cm] %.1f[kg]\n",p->Height,p->Weight); p=p->next; } printf("Delete data-\n"); printf("Please select delete data number:"); scanf("%d",&b); while( p->next != NULL && p->next->No != b) p = p->next; if( p->next == NULL ) return; temp = p->next; p->next = temp->next; while(p!=NULL){ printf("No,%d : %s\n",p->No,p->Name); printf("%.1f[cm] %.1f[kg]\n",p->Height,p->Weight); p=p->next; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2018/12/16 07:42

まず、インデントを直しましょう。話はそれから。
y_waiwai

2018/12/16 08:29

現状のコードはどういう動作をするんでしょうか
ksyiwk

2018/12/16 10:27

人数、名前、身長体重を入力し、それらを表示させます。
cateye

2018/12/16 11:32

“任意の場所”と言うのは、何番目とか言う事ですか?
ksyiwk

2018/12/16 13:55

はい、3つデータがあって3番目にデータを入れる場合、元の3つ目のデータは4番目に表示されるようにしたいです。
guest

回答3

0

リスト構造見の場合で配列を使用しない場合のコードを記載します.
配列を使用する場合は, 新たにインデックス用の外部変数を設けるなどして適切な処理を追加すればできると思います.

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}

投稿2018/12/18 03:03

Livenga

総合スコア85

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

人数、名前、身長体重を入力し、それらを表示させます。

問題無く、入力、表示ができましたが、何か、問題有るのでしょうか?

投稿2018/12/16 12:12

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

回答ではありません。が・・・

struct Data { int No; char Name[20]; double Height; double Weight; struct Data *next; } d[10]; int main() { struct Data *p; int i, a; p = &d[0]; printf("Please input the number of people:"); scanf("%d", &a); for (i = 0; i < a; i++) { printf("No,%d name : ", i + 1); scanf("%s", d[i].Name); printf("height : "); scanf("%lf", &d[i].Height); printf("weight : "); scanf("%lf", &d[i].Weight); if (i == a - 1) { d[i].next = NULL; } else { d[i].next = &d[i + 1]; } p->No = (int)i + 1; } while (p != NULL) { printf("No,%d : %s\n", p->No, p->Name); printf("%.1f[cm] %.1f[kg]\n", p->Height, p->Weight); p = p->next; } }

これってコンパイルできないですよね?
で、出来たとしてw・・・scanf()で、思い通りの入力できてますか?

投稿2018/12/16 08:40

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2018/12/16 12:11

普通にコンパイル、実行できましたが、、、。 Visual styudio 2017 コマンドラインから、 cl ***.c
cateye

2018/12/16 12:19 編集

私が言ったのは、include文がないからです。#include <stdio.h>を付ければコンパイルできます。
cateye

2018/12/16 12:51 編集

追加と言うのは、3個埋まってる時に4番目に入れると言うこと? 削除後のデータも活かすのでしょうか? 削除そのものはNoをクリアすれば擬似的に空に出来ると思いますが? リンクリストのnextを付け替えると結構きついかも・・・何か間違っている?σ(・_・)
pepperleaf

2018/12/17 12:01

> nclude文がないから 失礼しました。 ただ、stdio.h は大抵、付加されるので、気にしてませんでした。 リンクリストの操作は簡単に記述するが、ちょっと大変な気もします。(自分で作るのは、慣れていますが、説明は... です)
cateye

2018/12/17 13:03

元が配列なんでちょっと(データのコピーとか)嫌ですねw 操作性を考えたら双方向なんでしょうが・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問