c言語 二分探索木

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Kotatsu

c言語 二分探索木

#1

投稿記事 by Kotatsu » 1年前

学校課題で二分探索木を用いた電話帳検索システムを作成する課題が出ました。
質問はコンパイルエラー(問題文の下にあります)の原因とその解決方法、二分探索木の構築の過程をprintf関数で表示する方法を教えてほしいです。
以下が問題です。
// 基本問題2 要素追加関数
// 引数: target_node ... 評価するノード
// 引数: add_node ... 追加しようとしているノード
// 返り値: 構造体へのポインタ
// 動作: target_node と add_node を比べて処理する
Node *addData(Node *target_node, Node *add_node){

addData.c はキーボードから氏名・電話番号を入力し,addData関数を使って二分探索木
を構築するプログラムである.更に,木を構築する際の過程をprintf関数などで表示する
ようにし,実行結果として示すようにせよ.


コンパイルエラー

コード:

adddata.c: 関数 ‘main’ 内:
adddata.c:44:72: エラー: 構造体または共用体ではない何かのメンバ ‘name’ の要求です
       printf("名前を入力してください。\n");  scanf("%s", &p.name);
                                                                        ^
adddata.c:45:78: エラー: 構造体または共用体ではない何かのメンバ ‘cellnumb’ の要求です
       printf("電話番号を入力してください。\n");  scanf("%s", &p.cellnumb);
途中まで過去の掲示板での質問などを参考に自分で作成したプログラムが以下です。

コード:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NUMBER 64

typedef struct node{
  char name[NUMBER];
  char cellnumb[NUMBER];
  struct node *left;
  struct node *right;
}Node;

Node *addData(Node *target_node, Node *add_node)
{
  int n;
  n = strcmp(target_node->name, add_node->name);
  if(target_node == NULL){
    Node *target_node = malloc(sizeof(Node));
    strcpy(target_node->name, add_node->name);
    strcpy(target_node->cellnumb, add_node->cellnumb);
    target_node->left = NULL;
    target_node->right = NULL;
  }
  else if(n > 0){
    target_node->left = addData(target_node->left, add_node);
  }
  else if(n < 0){
    target_node->right = addData(target_node->right, add_node);
  }

}

int main(void)
{
  int answer;
  Node *root;
  Node *p;

  root = NULL;
  do{
    int answer;
    printf("ノードを追加しますか?\n[Yes] ==> 1   [No] ==> 0");  scanf("%d",&answer);
    if(answer == 1){
      printf("名前を入力してください。\n");  scanf("%s", &p.name);
      printf("電話番号を入力してください。\n");  scanf("%s", &p.cellnumb);
      p->left = NULL;
      p->right = NULL;
      root = addData(root, p);
    }
  }while(answer == 1);

  return 0;
}


アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: c言語 二分探索木

#2

投稿記事 by みけCAT » 1年前

Kotatsu さんが書きました:
1年前
質問はコンパイルエラー(問題文の下にあります)の原因とその解決方法、
コンパイルエラーの原因は、書かれている通り構造体でも共用体でもないp (ポインタ) に対し . 演算子を用いてメンバアクセスしようとしたことです。
解決方法は、left や right にアクセスするときと同様に -> 演算子を用いるといいでしょう。

ちなみに、このままでは p を初期化せずに p が指す構造体のメンバにアクセスしようとしているので、実行時にエラーになる可能性が高いでしょう。
Kotatsu さんが書きました:
1年前
二分探索木の構築の過程をprintf関数で表示する方法を教えてほしいです。
二分探索木の構築の過程をprintf関数で表示するプログラムを書き、実行すればいいでしょう。
まずは「二分探索木の構築の過程」とはどのようなものかを定義するか、定義を探しましょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: c言語 二分探索木

#3

投稿記事 by みけCAT » 1年前

addData 関数もおかしいですね。

まず、target_node を NULL と比較していますが、その前に無条件で target_node をデリファレンス (target_node->name にアクセス) しているので、この比較では未定義動作を避けられません。
target_node のデリファレンスのに target_node が NULL かどうかをチェックするべきです。

次に、戻り値を代入する処理があるにもかかわらず、return 文がありません。
これでは、代入される値は不定となり、正常な処理ができる可能性が低くなるでしょう。
今回の場合、引数として与えられた target_node が NULL の場合は新たに確保したノードへのポインタを、
そうでない場合は与えられた target_node を返すのがよいでしょう。

-----------------

ついでに、scanf 関数の書式 %s は char* 型のデータを要求します。
式中の配列は (sizeof 演算子に渡す場合などの例外を除いて) 自動で先頭要素へのポインタに変換されます。
&p->name を渡してしまうと、これは配列 p->name へのポインタ、すなわち char(*)[NUMBER] 型なので、要求されている型とは違う型のデータを渡すことになり、未定義動作となります。
よって、ここの & 演算子は削除するべきです。
&p->cellnumb についても同様です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
usao
記事: 1889
登録日時: 11年前

Re: c言語 二分探索木

#4

投稿記事 by usao » 1年前

// 基本問題2 要素追加関数
// 引数: target_node ... 評価するノード
// 引数: add_node ... 追加しようとしているノード
// 返り値: 構造体へのポインタ
// 動作: target_node と add_node を比べて処理する
これ,問題の原文そのものなの?
全体的にイミフすぎる.

> 返り値: 構造体へのポインタ

とか,情報量ゼロすぎるだろ…… 何を返すんだよ?


Kotatsu

Re: c言語 二分探索木

#6

投稿記事 by Kotatsu » 1年前

みけCAT様、丁寧にご回答いただきありがとうございます。全て読ませていただきました。しかしながら、同様の質問の投稿を他サイトでも行ってしまったため、この質問を閉め切ろうと思います。
teratail 構造体または共用体ではない何かのメンバ ‘xxx’ の要求ですというコンパイルエラーの原因と解決法
teratail プログラムを実行するとSegmentation fault (コアダンプ)と表示されてしまう
マルチポストが禁止行為であることは承知していましたが、焦りから軽率な行いをしてしまいました。丁寧な解説を頂いたのに、大変申し訳ございません。

Kotatsu

Re: c言語 二分探索木

#7

投稿記事 by Kotatsu » 1年前

usao様、不快な思いをさせてしまい申し訳ありませんでした。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: c言語 二分探索木

#8

投稿記事 by みけCAT » 1年前

ここではマルチポストは禁止行為ではありません。
相互リンクすればマルチポストOK
相互リンクした場合のみ複数の掲示板で同じ質問しても OK

複数の掲示板で同じ質問をすることをマルチポストといい、大抵禁止されています。

しかし、ここでは相互リンクし、リンク先の掲示板でマルチポストが許されていれば

マルチポストはOKとしています。複数の掲示板で同じ質問をするときは相互リンクし、

どこの掲示板で同じ質問をしているか明確にして下さい。
(フォーラムルールより引用)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

“C言語何でも質問掲示板” へ戻る