前提・実現したいこと
ハッシュ表をチェイン法で実現したいです
検索する関数とエラー関数で以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
該当のソースコード
#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/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
fatal_error は引数 s に `%` が含まれていると問題が発生しますので、fprintf(stderr, "%s", s); とか fprintf(stderr, "Fatal Error: %s\n", s); のようにすると良いでしょう。
find は引数が int key なのに char の配列を渡してるところがあります。他にも hash の引数とかいろいろ怪しいですね…。
find の中は(char key)とかにした方が良いですか??
hashの引数とかは(p=table[hash(key)]の書き方がいけないということですか
ハッシュ値を作成する8桁の数字は、hashに文字列として渡すのですね。
これは、学籍番号ですか。
学籍番号は、00000000~99999999の数字を入力する前提で良いですか。
(学籍番号が123の場合は00000123と入力する)
insertへdouble型のデータを渡すようになっていますが、main側ではそのデータをを渡してないですね。
このdouble型のデータは、どのような意味のデータですか?
はい!8桁の数字ならなんでも良いです!分かりにくかったので数字に直しました、
すみません、mainの中が消えていました、追加しました。
double型のデータはハッシュ表を理解するためなので特に意味は無く、とりあえずデータを格納して、
まだ不完全ですがcase4で全て表示したいです
インデントがずれてますね。
```ここに言語を入力
コード
```
が表示されたとき
```①
②
```
①の個所にCと入力し
②の個所にあなたのソースを貼り付けます。
つまり、以下のようにします。
```C
あなたのソースをはりつけたもの
```
そうすると、きれいに、インデントがそろいます。
すみません、ここのソースコードの記載の仕方が中々慣れなくて、、
なおしました
まだ、直ってませんが、とりあえず、回答欄のコメントにこれから回答します。
回答5件
あなたの回答
tips
プレビュー