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

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

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

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

解決済

c言語でハッシュ表を実装したいです

kyapi
kyapi

総合スコア0

C

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

5回答

0評価

0クリップ

2125閲覧

投稿2021/01/08 08:09

編集2022/01/12 10:58

前提・実現したいこと

ハッシュ表をチェイン法で実現したいです
検索する関数とエラー関数で以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

該当のソースコード

#include <stdio.h> #include <stdlib.h> /* ハッシュ法の定義 */ #define BUCKET_SIZE 10 /* ハッシュ表の大きさ */ typedef struct cell{ int key; double data; struct cell *next; } CELL; /* ハッシュ表の本体はCELL型ポインタの配列として実現している */ CELL table[BUCKET_SIZE]; /* init --ハッシュ表を初期化する ハッシュ表に含まれる全てのパケットにNULLをセット ハッシュ表を使う前に必ずセットしなければならない */ void init() { int i; /* BCKET_SIZEだけ繰り返して table[i]の中をNULLにして空にする */ for(i=0; i<BUCKET_SIZE; i++) table->next = NULL; } /* エラーメッセージをプリントしてexitする関数 */ /* ポインタ(アドレス)の先のデータを読み取り専用にする */ void fatal_error(char *s) { /* fprintf関数を使ってstderrで標準エラーを出力する*/ fprintf(stderr,"%s\n",s); exit(1); /* 異常終了 */ } /* ハッシュ値を計算する関数 パラメータとしてキーを与えると そのキーに対するハッシュ値(int型)を返す*/ int hash(int s) //修正 { /* キーの値を二乗してその中央値をとることで均等にしている */   return(s % BUCKET_SIZE); } /* find -- ハッシュ表を探索する 探したいキーの値をパラメータとして受け取る 成功したらキーを持つDATAへのポインタを返す (構造体CELL型のメンバdataへのポインタ) 見つからなければNULLを返す */ CELL *find(int key) { CELL *p; /* p=table[hash(key)]でそのキーが所属しているべきバケットから 連結リストへのポインタを取り出している for文本体では連結リストをたどりながら線形探索する */ for(p=&table[hash(key)]; p!=NULL; p=p->next) /* もし2つのキーが等しければ成功 */ if(key==p->key) /* キーを持つDATAへのポインタを返す */ return p;//&p->data; else /* 等しくなければ見つからないとしてNULLを返す*/ return NULL; } return NULL; } /* insert -- ハッシュ表にデータを挿入する 2つのパラメータを受け取る ①keyは挿入されるデータ持っているキーの値 ②dataはDATA *型で挿入されるデータへのポインタ データを登録する際に同じキーを持つデータがすでに登録されているかどうかをチェックする キーが重複していない場合、登録に成功したら1を返す 登録に失敗(すでに同じキーを持つデータがある) したら0を返す */ int insert(int key,double data) { CELL *p; int h; /* キーが重複していないか関数findを呼び出してチェックする 重複していたら0を返す もしNULLでないなら重複していない */ if(find(key) != NULL) return 0; /* もし重複していないなら関数mallocを呼び出し、 データを格納するセルを割り当てる */ if((p=malloc(sizeof(CELL))) == NULL){ /* もしセルの割り当てに失敗したらプログラムの実行を中止する */ fprintf(stderr,"out of momory\n"); exit(2); } /* セルを割り当てたらセルにキーとデータをセットして キーの値に対応するバケットに連結する*/ h=hash(key); p->key=key; p->data=data;//*dataだった p->next=&table[h]; table[h]=*p; return 1; } /* delete -- ハッシュ表から削除する 削除したいキーを受け取る 該当するキーを持ったデータが存在し、 削除に成功したら1を返す 該当するキーを持ったデータが見つからなければ何もしないで、 0を返す */ /* 最初にバケットを決め、 そのバケットに属する連結リストに対して削除の処理を行う */ int delete(int key) { int h; CELL *p,*q; h=hash(key); /* そのバケットは空か */ if(&table[h] == NULL) return 0; /* リストの先頭のセルが削除すべきデータか? */ if(key==table[h].key){ p=&table[h]; table->next=p->next;//&table[h]=p->next; free(p); /* 削除に成功したら1を返す */ return 1; } /* リストの二番目以降のセルについて順番にチェックする */ for(q=&table[h],p=q->next; p!=NULL; q=p,p=p->next){ if(key==p->key){ q->next=p->next; free(p); /* 削除に成功したら1を返す */ return 1; } } /* 該当するキーを持ったデータが見つからなければ 削除に失敗したとして0を返す */ return 0; } static void hash_print(void) { int i; CELL *current = NULL; /* バケットの数だけ繰り返す */ for(i = 0; i < BUCKET_SIZE; i++){ if(&table[i] != NULL){ printf("table[%d]",i); /* currentをi番目にしておく */ current = &table[i]; /* currentがNULLでない間、次々表示させる*/ for(; current != NULL; current = current->next){ printf(" key=%d", (current->key)); printf(" data=%f", (current->data)); } printf("\n"); } } } int main(void) { /* ハッシュ表を初期化する */ init(); int key; /* 数字を入力するための配列変数 */ double data; int hashval; /* hash関数のハッシュ値を受け取る変数 */ int mn=0; /* メニュー選択の数字を入れる変数 */ int a; /* insert関数の戻り値を受け取る変数 */ int c; /* delete関数の戻り値を受け取る変数 */ CELL *fp; /* find関数の戻り値を受け取る変数 */ printf("チェイン法をします\n"); do{ printf("メニューを選んでください\n1=追加 2=検索 3=削除 4=ひょうじ 9=終了\n"); scanf("%d",&mn); switch(mn){ case 1: printf("8桁の数字を入力してください\n"); scanf("%d",&key); printf("データを入力してください\n"); scanf("%lf",&data); /* ハッシュ値を得る */ hashval=hash(key); printf("数字=%d ハッシュ値=%d\n",key,hashval); a=insert(key,data); if(a==1) printf("Done\n"); else printf("AlreadyExsits\n"); break; case 2: printf("検索する8桁の数字を入力してください\n"); scanf("%d",&key); fp=find(key); if(fp==NULL) printf("NotExsits\n"); else printf("key=%d 検索した値=%f\n",fp->key,fp->data); break; case 3: printf("削除する8桁数字を入力してください\n"); scanf("%d",&key); c=delete(key); if(c==1) printf("Done\n"); else printf("NotExsits\n"); break; case 4: printf("ひょうじします\n"); /* リストの要素の値を表示する */ hash_print(); break; case 9: printf("終了します\n"); break; default: printf("エラー:メニューの中の数字を入力してください\n"); } }while (mn !=9); return 0; }

3つの警告と1つのエラーが出ています

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori
hoshi-takanori

2021/01/08 08:39

fatal_error は引数 s に `%` が含まれていると問題が発生しますので、fprintf\(stderr, "%s", s\); とか fprintf\(stderr, "Fatal Error: %s\\n", s\); のようにすると良いでしょう。 find は引数が int key なのに char の配列を渡してるところがあります。他にも hash の引数とかいろいろ怪しいですね…。
kyapi
kyapi

2021/01/08 10:12

find の中は(char key\)とかにした方が良いですか?? hashの引数とかは\(p=table\[hash\(key\)\]の書き方がいけないということですか
tatsu99
tatsu99

2021/01/09 02:41 編集

ハッシュ値を作成する8桁の数字は、hashに文字列として渡すのですね。 これは、学籍番号ですか。 学籍番号は、00000000~99999999の数字を入力する前提で良いですか。 (学籍番号が123の場合は00000123と入力する) insertへdouble型のデータを渡すようになっていますが、main側ではそのデータをを渡してないですね。 このdouble型のデータは、どのような意味のデータですか?
kyapi
kyapi

2021/01/09 06:51

はい!8桁の数字ならなんでも良いです!分かりにくかったので数字に直しました、 すみません、mainの中が消えていました、追加しました。 double型のデータはハッシュ表を理解するためなので特に意味は無く、とりあえずデータを格納して、 まだ不完全ですがcase4で全て表示したいです
tatsu99
tatsu99

2021/01/10 05:10

インデントがずれてますね。 ```ここに言語を入力 コード ``` が表示されたとき ```① ② ``` ①の個所にCと入力し ②の個所にあなたのソースを貼り付けます。 つまり、以下のようにします。 ```C あなたのソースをはりつけたもの ``` そうすると、きれいに、インデントがそろいます。
kyapi
kyapi

2021/01/10 05:22

すみません、ここのソースコードの記載の仕方が中々慣れなくて、、 なおしました
tatsu99
tatsu99

2021/01/10 05:26

まだ、直ってませんが、とりあえず、回答欄のコメントにこれから回答します。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C

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