最近C言語でリスト構造を勉強したので自己流でリスト構造のプログラムを作成したのですが正常に作動しません。どなたか解決法を教えてください。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*データ*/
typedef struct {
int num; //学籍番号下三桁
char name[16]; //氏名
}data_t;
/*ノード*/
typedef struct node {
data_t data; //データ
struct node *nextnode; //後ろのノードへのポインタ
}node_t;
/*関数プロトタイプ宣言*/
node_t *make_node(data_t, node_t *);
void add_data(node_t *);
void remove_data(node_t *);
void search_data(node_t *);
void show_data(node_t *);
void release(node_t *);
int main(void)
{
int menu;
node_t *node=NULL;
do {
puts("");
puts("***メニューの選択***");
puts(" 1.データの追加");
puts(" 2.データの削除");
puts(" 3.データの検索");
puts(" 4.データの表示");
puts(" 5.終了");
printf("メニューの選択:"); scanf("%d", &menu);
puts("");
switch (menu)
{
case 1: add_data(node); break;
case 2: remove_data(node); break;
case 3: search_data(node); break;
case 4: show_data(node); break;
case 5: puts("プログラムを終了"); break;
default:puts("番号を再入力"); break;
}
} while (menu != 5);
release(node);
system("pause");
return 0;
}
/*新規ノードの作成*/
node_t *make_node(data_t data, node_t *nextnode)
{
node_t *p;
p = malloc(sizeof(node_t));
if (p == NULL) {
puts("領域確保に失敗");
return NULL;
}
else {
p->data = data;
p->nextnode = nextnode;
return p;
}
}
/*データの追加*/
void add_data(node_t *node)
{
data_t data;
node_t *p=node;
puts("***追加するデータの入力***");
printf("学籍番号の下二桁の番号:"); scanf("%d", &data.num);
printf("氏名:"); scanf("%s", data.name);
while (p->nextnode != NULL) {
p = p->nextnode;
}
p = make_node(data, NULL);
}
/*データの表示*/
void show_data(node_t *node)
{
node_t *p=node;
if (p ==NULL) {
puts("データがありません。データを追加してください。");
return;
}
while (p!=NULL){
printf("番号%*s氏名\n",6,"");
printf("%2d %10s\n", (p->data).num, (p->data).name);
p = p->nextnode;
}
}
/*データの削除*/
void remove_data(node_t *node)
{
int num;
node_t *pre;
if(node==NULL)
puts("データは見つかりませんでした。"); return;
puts("***データの削除***");
printf("番号の入力:"); scanf("%d", &num);
while (node->nextnode != NULL) {
if ((node->data).num == num) {
pre = node->nextnode;
free(node);
return;
}
pre = node;
node = node->nextnode;
}
puts("データは見つかりませんでした。");
}
/*データの検索*/
void search_data(node_t *node)
{
int num;
node_t *p=node;
puts("***データの検索***");
printf("番号の入力:"); scanf("%d", &num);
if (node == NULL)
puts("データは見つかりませんでした"); return;
while (p->nextnode != NULL) {
if ((p->data).num == num) {
puts("---データを発見---");
printf("氏名:%s\n", (p->data).name);
return;
}
p = p->nextnode;
}
puts("データは見つかりませんでした");
}
/*データの後処理*/
void release(node_t *node)
{
node_t *p;
if (node = NULL) return;
while (node->nextnode != NULL) {
p = node;
node = node->nextnode;
free(p);
}
}
No.4ベストアンサー
- 回答日時:
とりあえず #1 に 2点ほど突っ込んでおく.
・「make_node()関数でmallocを何度も呼び出すのはパフォーマンス的に良いとは言えません」っていわれてもしょうがないっちゃしょうがないんだよな.
・「add_data()関数でwhileループをした後pはNULLを指しますので、NULLポインタへの代入でエラーになります」は多分気のせいだと思う. 「while ループのあと」では「NULL ポインタ経由のアクセス」はしてないからね. まあ, だからといって期待した動作はしないはずだけど.
あと remove_data でリスト構造をもろにぶち壊してくれる.
ついでにいうとノードの構造体は
typedef struct node_t {
data_t data; //データ
struct node_t *nextnode; //後ろのノードへのポインタ
}node_t;
と書いてもいい (他の方法もあり) んだけど, あんまりやる人はいない気がする.
No.5
- 回答日時:
No1の者です
No4の方の言う通りadd_data()関数の指摘した部分は勘違いだったようです。
また、リスト構造を勉強されているということで、パフォーマンスや、データ構造の話をするのはすこし場違いでした。お騒がせしました。
No.3
- 回答日時:
add_data()は指摘されているとおり、ヌルポアクセスで吹っ飛びます。
NULL->nextnodeの参照なので。
>if(node==NULL)
>puts("データは見つかりませんでした。"); return;
nodeの内容に関わらず、ここから先には進みません。
必ずreturnします。
No.1
- 回答日時:
まず、どこがどう動作しないのかを明確にしてください。
正確な回答ができません。読んでいて気付いたことを挙げていきます。
main()関数内でnodeの領域が確保されていないので、ノードの操作すべてがメモリアクセスエラーで失敗します。
add_data()関数でwhileループをした後pはNULLを指しますので、NULLポインタへの代入でエラーになります。
make_node()関数でmallocを何度も呼び出すのはパフォーマンス的に良いとは言えません。学籍番号と氏名というデータであれば、配列を使ったほうが適切です。
remove_data()関数以降は見ていませんが、main()が動けばデバックできると思います。頑張ってください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- 工学 永久機関を磁石で作れませんか?ずっと引き寄せる力があると思うのですが何かに利用できないのでしょうか? 2 2022/06/19 08:23
- その他(自然科学) 永久機関を磁石で作れませんか?ずっと引き寄せる力があると思うのですが何かに利用できないのでしょうか? 3 2022/06/22 10:57
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
linuxのシェルでファイル名に先...
-
離散フーリエ変換のプログラム...
-
C言語 構造体の名前欄?を小文...
-
PINVOKEで構造体配列をマーシャ...
-
C言語 ファイル内のデータと入...
-
'dataType' 引数を Null にする...
-
結城未来さんの年齢
-
エクセルVBA:日付データの変換...
-
C言語についてです! 同じ年の...
-
画像処理のチェーンコード
-
matlabのソースコードをpython...
-
C言語 2分木探索について質問です
-
printfの%eで指数部分の桁数を...
-
掲示板CGIで新着順ではなく古い...
-
C言語 平均を求めるプログラム
-
C言語でPBYTE型からDOUBLE型へ変換
-
UTF-8で5~6バイトになる文字コ...
-
DataGridViewの特定列に入力さ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
printfの%eで指数部分の桁数を...
-
【Excel VBA】10進数を2進数に...
-
int型(2バイト)データの分割
-
pythonでDBのカラム名で取得し...
-
エクセルVBA:日付データの変換...
-
C#でのswitch文
-
linuxのシェルでファイル名に先...
-
C言語の構造体にてバブルソート...
-
c言語での wavファイルの編集(...
-
'dataType' 引数を Null にする...
-
H8/36064を使ったシリアル通信...
-
オセロゲーム 2次元配列で困...
-
10個の実数に対する降順ソート...
-
c言語の多次元配列で1から100ま...
-
c言語 配列から数字だけをint型...
-
matlabのソースコードをpython...
-
Cのプログラムがどうしても動き...
-
テキストファイルの結合について
おすすめ情報