- ベストアンサー
辞書検索プログラムの続きです。
void read_dic() { char eng2[20], jp2[40]; FILE *fp; int i=0; if((fp=fopen("dic.txt", "r"))==NULL) { printf("\n ファイルがありません\n"); exit(1); } else { printf("読み込み中...\n"); while (!feof(fp)) { fscanf(fp, "%s %s", eng2, jp2); strcpy(table[i].eng, eng2); strcpy(table[i].jp, jp2); i++; if(i>=100){ printf("辞書のテーブルがいっぱいです\n"); fclose(fp); exit(1); } } fclose(fp); printf("読み込み終了\n"); n = i; } } int hash(char *tango) { int h=0,p=256; while (*tango!='\0') { h = h*p + *tango; h = h%BUCKET_SIZE; tango++; } return(h); } struct cell *find(char *tango) { int a; struct cell *q; a=hash(tango); if(bucket[a].chain==NULL) return NULL; else{ q=bucket[a].chain; while ((strcmp(q->eng,tango))!=0){ if(q->next==NULL) return NULL; else q=q->next; } return q; } } 以前の投稿は http://oshiete1.goo.ne.jp/kotaeru.php3?qid=109202
- ya-co
- お礼率16% (1/6)
- C・C++・C#
- 回答数5
- ありがとう数1
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
まだ抜けていました。 ハッシュテーブルを検索するときに table[x]->next が NULL なのかどうなのかを チェックしますので、テーブルを作成するときまたは初期化するときに、この next を NULL にしておかなければうまく動かない可能性があります。 実行環境によっては明示的に初期化しなくても NULL になっている場合もあります が、他人任せにしておくのはよくありません。 read_dic()関数内の読み込みのところで strcpy(table[i].eng, eng2); strcpy(table[i].jp, jp2); とやっているところがあるので、この直後に次の行を追加して下さい。 table[i].next = NULL; ついでに補足すると、init_table()が呼び出されていませんので、read_dic() を呼び 出す前ぐらいに init_table() も呼び出してあげましょう。
その他の回答 (4)
- Jizou
- ベストアンサー率80% (4/5)
ranxさんがすでに指摘されている点は、少なくとも修正が必要です。 それに加えて、ハッシュテーブル bucket[] を作成する処理が全く抜けています ので今のままでは「白紙の辞書」を見て検索しているに過ぎません。 ハッシュテーブル作成処理 例えば、こんな感じの関数を作って read_dic() の後で hash_table() を 呼び出します。 void hash_table() { int i, h; struct cell **p for( i=0; i<BUCKET_SIZE; i++ ) bucket[i].cell = NULL; for( i=0; i<n; i++ ){ h = hash( table[i].eng ); p = &(bucket[h].cell); while( *p != NULL ) p = &(*p->next); *p = &(table[i]); } } (上記のソースには全角の空白文字が使われています。全角を半角に変換して 使って下さい)
- pasta500g
- ベストアンサー率46% (30/65)
自己フォロー。 >またmain()で使用しているread_dic()関数とfind()関数が記載されていないの >で、その信憑性も不明です。(「まだ続きます。。。」に続くのかな?) この部分については次の質問に書かれていましたね。失礼しました。m(_ _)m
- pasta500g
- ベストアンサー率46% (30/65)
まず「実行できません。」では具体的にどういう症状なのか全くわかりません。 command not found なのですか?たぶん違いますよね。詳しく書きましょう。 またmain()で使用しているread_dic()関数とfind()関数が記載されていないので、その信憑性も不明です。(「まだ続きます。。。」に続くのかな?) 失礼ですが学生さんでしょうか?まず有効な回答が期待できそうな質問の仕方を精進して下さい。そうすることで自分の頭の中が整理できて自己解決できることも多いです。プログラミングってやつは。 それから人にソースを見てもらうならインデント付けくらいは何とかしましょう。 以上、苦言を並べてしまいましたが、あなたの成長を願ってあえて辛辣に書かせて頂きましたのでご理解ください。
- ranx
- ベストアンサー率24% (357/1463)
全体を見たわけではないので自信なしとしておきますが、 struct cell *find(char *tango); と宣言されているのに、その戻り値 p= find(tango) を table[p].jp と配列の引数にしているのは変ですね。 p->jp のおつもりなのでは。
関連するQ&A
- ハッシュ法が得意な人お願いします。
辞書検索プログラムが実行できません。どこがおかしいか教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUCKET_SIZE 100 typedef struct pointer { struct cell *chain; }pointer; struct cell{ char eng[20]; char jp[40]; struct cell *next; } table[BUCKET_SIZE]; int n; void read_dic(); void init_table(); int hash(char *tango); void main(); struct cell *find(char *tango); struct pointer bucket[BUCKET_SIZE]; void init_table() { int i; for (i=0;i<BUCKET_SIZE;i++){ strcpy(table[i].eng,"0"); strcpy(table[i].jp,"0"); } } void main() { int m; struct cell *p; char tango[20]; read_dic(); while(1){ printf("\n単語を入力: "); scanf("%s", tango); if (strcmp(tango, "*") == 0){ printf("検索を終了\n"); exit(0); } if((p= find(tango)) == NULL) printf("単語は見つかりませんでした\n"); else printf("訳語: %s \n", table[p].jp); } } まだ続きます。。。
- 締切済み
- C・C++・C#
- 再検索プログラムについて
再びすみません。 先ほどは別の問題で質問させていただきました。 今回は、address2.txtに保存してあるアドレスを検索するプログラム(下記)なのですが、 (1)アドレスが一致しないときに、再び検索できるようにしたいのですが、うまくできません。 (2)address2.txtに登録してあるアドレスの7行目以降は検索されなくなってしまいます。 これらの問題解決のご指摘をお願いします。 #define FNAME "address2.txt" #define RECORDLEN 16 #include <stdio.h> #include <stdlib.h> #include <string.h> char *format = "%-15s\n"; int main() { FILE *fp; char search[16], address[16],ans[8]; int no = 0, find = 0; fp = fopen(FNAME, "r+"); if(fp==NULL){ perror("ファイルエラー\n"); return -1; } printf("アドレスの入力-- "); gets(search); while (1) { fseek(fp, RECORDLEN * no++, SEEK_SET); if (fscanf(fp, "%s", address) == EOF) break; if (strstr(address, search) != NULL) { find++; printf("アドレス: %s\n", address); } } if(find>=1){ printf("アドレスが一致しました。" ); } else { printf("アドレスが一致しません。\n"); printf("再度検索し直しますか?(Y/N)\n"); gets(ans); if(ans[0]=='y'||ans[0]=='Y') continue; else break; } fclose(fp); return 0; }
- ベストアンサー
- C・C++・C#
- C言語のプログラムについてご指導願えますか?
ファイルを読み込み、そのなかにI,We,You,He,She,Theyの単語がいくつかるかカウントするプログラムを作成したいのですが、単語のカウントがうまくできません。 下記に作成したソースを記載しますので、間違っている箇所を指摘していただけませんか? #include <stdio.h> #include <stdlib.h> #include <string.h> int main( void ) { char filename[FILENAME_MAX]; int j=0; int k=0; int l=0; int m=0; int n=0; int o=0; FILE *fp; gets(filename); fp = fopen(filename,"r"); { if(fp==NULL) { printf("ERROR"); return -1; } if(strcmp("I",fp)==0) { j++; } if(strcmp("We",fp)==0) { k++; } if(strcmp("You",fp)==0) { l++; } if(strcmp("He",fp)==0) { m++; } if(strcmp("She",fp)==0) { n++; } if(strcmp("They",fp)==0) { o++; } } printf("I: %d\n",j); printf("We: %d\n",k); printf("You: %d\n",l); printf("He: %d\n",m); printf("She: %d\n",n); printf("They: %d",o); fclose(fp); return 0; }
- 締切済み
- その他(学問・教育)
- プログラムが動きません。
プログラムが動きません。 ファイルuniqipにはIPアドレスが書き込まれています。そのファイルからIPアドレスを文字列ipに格納します。 ファイルtmp4には、85.114.143.2 34f4ff4acb18802170a939ae42dcd5ee0eeccda4 のようにIPアドレスとハッシュ値が書き込まれています。 tmp4に現れるIPアドレスで、uniqipに一致するものに対応するハッシュ値を printf("file%d,%s\n",i,hash); の形で出力しようと思いましたが、うまくいきません。 何がまずいのでしょうか? #include <stdio.h> #include <string.h> //ひとつのIPアドレスに現れるユニークなハッシュ値の数をカウントする int main() { FILE *fp,*gp; char ip[269730][16]; char ip2[16]; char hash[42]; int i,j; fp = fopen("uniqip","r"); if(fp == NULL){ printf("can not open the file.\n"); return 1; } for(i=0;i<267930;i++) { fscanf(fp,"%s",ip[i]); //printf("%s\n",ip[i]); } fclose(fp); ////////////////////////////////////////////////////////////////////////////////////////////////////// gp = fopen("tmp4","r"); if(gp == NULL){ printf("can not open the file.\n"); return 1; } for(i=0;i<267930;i++){ for(j=0;j<2470766;j++){ fscanf(gp,"%s %s",ip2,hash); printf("%s\n",ip[i]); if(!strcmp(ip[i],ip2)) { printf("file%d,%s\n",i,hash); } } } return 0; }
- ベストアンサー
- C・C++・C#
- この間質問した内容です。
この間質問した内容です。 #include <stdio.h> #include <stdlib.h> #include <string.h> int knum; int kNO; char **kstr; int *ans; int get_score(void) { FILE *fp; int best; if((fp = fopen("score.txt","r")) == NULL) { printf("初回起動ですね。\nスコアファイルを新規作成します。\n"); best = 0; } else { fscanf(fp,"%d%d",&best,&knum); printf("最高点は%d問中%d問です。\n",knum,best); fclose(fp); } } int read_kuizu(void) { int i; FILE *fp; if((fp = fopen("kuizu.txt","r")) == NULL) return(-1); fscanf(fp,"%d",&kNO); if((kstr = (char **)calloc(kNO,sizeof(char *))) == NULL) return(-1); if((ans = (int *)calloc(kNO,sizeof(int))) == NULL) return(-1); for(i = 0; i<kNO; i++) { char temp[1024]; size_t len; fscanf(fp,"%s",temp); fscanf(fp,"%d",&ans[i]); len = strlen(temp); if((kstr[i] = (char *)malloc(len + 1)) == NULL) return(-1); strcpy(kstr[i],temp); } fclose(fp); return(0); } int kuizu_game(void) { int i; int score = 0; for(i = 0; i<kNO; i++) { int unans; printf("\nクイズ%d\n", i + 1); printf("%s YES(0)/NO(1)\n",kstr[i]); do { printf("答を選んで番号を入力して下さい。=>\n"); scanf("%d",&unans); } while(unans!=0 && unans!=1); if(unans == ans[i]) { score++; printf("正解です!\n"); } else printf("残念ながら不正解・・・\n"); } return(score); } void result(int best,int score) { printf("\n今回%d問中%d問正解でした。\n",kNO,score); printf("前回は%d問中%d問正解していました。\n",knum,best); } int main(void) { int score; int best; best = get_score(); if(read_kuizu() == -1) { printf("エラー\n"); return(-1); } score = kuizu_game(); result(best,score); if(score>best) { printf("最高点を更新!\n"); best = score; } FILE *fp; fp = fopen("score.txt","w"); fclose(fp); return(0); } 一応ここまでやってコンパイルしたのですが、クイズのファイルを読み込む事ができません。どこか間違ってるんでしょうか?
- ベストアンサー
- C・C++・C#
- C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問
C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問です! ファイルを開いた後でエラーとなるのですが、何が足りないのでしょうか? ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int k,i=0; int num[10]; char na[10][20]; fp=fopen(argv[1],"r"); if(fp==NULL){ printf("ファイルを開けません\n"); return 1; }else{ printf("開けた\n"); } while(fgets(str,sizeof str,fp)!=NULL){ tp=strtok(str," "); num[i]=atoi(tp); tp=strtok(NULL," "); strcpy(na[i],tp); i++; } printf("%d\n%s\n",num[0],na[0]); printf("%d\n%s\n",num[1],na[1]); fclose(fp); return 0; }
- ベストアンサー
- C・C++・C#
- CSVファイルの内容を構造体に格納したい(Unix使用)。
こんにちは。私は30代の男性です。 「名前」「身長」「体重」が記載されたCSVファイルの内容を読み取って、構造体の「name」「height」「weight」に格納するプログラムを作っています。CSVの内容は A,175,80 B,167,89 C,155,45 ・ ・ ・ Z,188,70 だと仮定します。数値が読み取れているか、下記のように「tp = strtok(file_image, ",\n" );」の前後に「printf("%s\n", file_image);」を置いてみたら、strtok前では全て表示されるのに、strtok後では「ABC」しか表示されません。これでは全てのデータを構造体に格納できないので、困っています。 1.どのようにすれば、数字も取り出せる(読み取れる)でしょうか? 2.効率よく構造体に格納するには、どのようにしたらよいでしょうか? アドバイスを頂ければ幸いです。宜しくお願いいたします。 #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> int main(int argc, char *argv[]) { FILE *fp = NULL; int rtn = 0; if ((fp = fopen(argv[1], "r")) == NULL) { printf("ファイルオープンに失敗しました。\n"); return 1; } if (argc != 2) { printf("ERROR: オプションの数に過不足があります。\n"); return 1; } rtn = change_csv(fp); return 0; } int change_csv(FILE *fp) { int i; int j; char file_image[256]; /* 読み込んだ先のメモリの領域 */ char *tp; for (i = 0; i <= 256; i++) { if (fgets(file_image, 256, fp) == NULL) { if (ferror(fp) != 0) { printf("ERROR: 読み込みに失敗しました。\n"); return 1; } } if (feof(fp) != 0) { break; } printf("%s\n", file_image); tp = strtok(file_image, ",\n" ); printf("%s\n", file_image); } fclose(fp); return 0; }
- ベストアンサー
- C・C++・C#
- 再帰プログラム
#include<stdio.h> int rstrlen(char*); int main(void) { char str[100]; printf("文字列を入力してください\n"); gets(str); printf("文字数は %d です\n",rstrlen(str)); return 0; } int rstrlen(char *p) { if(*p){ p++; return 1+rstrlen(p); } else return 0; } 文字数を計算するプログラムです。 if(*p)の*pとはNULLを表しているのですか?
- ベストアンサー
- C・C++・C#
- ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込
ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込みプログラム」をそのままコンパイルして実行しようと思ったのですが、 sample.c: In function 'main': sample2.c:9: warning: return type of 'main' is not 'int' と、表示されてしまいます。 プログラミング初心者なので、どこが間違っているのかわかりません。 回答またはアドバイスの程、よろしくお願いいたします。 ネットで落ちていたプログラムを以下に記載します。 sample2.c #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("コマンドの入力形式が間違っています.\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("ファイルがオープンできません[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("データが不正です[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("エラー(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("エラー(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("エラー(3)\n"); break; } if(*wp != '\0'){ printf("エラー(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); }
- ベストアンサー
- C・C++・C#
- ポインタと配列
次のソースで、結果表示でポインタを使いたいのですが、うまくいきません。1件しか表示されないのです。 ポインタの扱いがおかしいのだと思いますが、どうしたらよいでしょうか? #include <stdio.h> #include <string.h> int search(char key[256],FILE *fp,char *result[256][256]); main(void) { FILE *fp; int rep,n,i; char x[256],key[256],*result[256][256]; printf("検索キーワードを入力してください。\n" "キーワード>"); gets(key); if((fp=fopen("personal.txt","r"))==NULL) { printf("ファイルをオープンできません\n"); exit(1); } printf("=====検索結果=====\n"); n=search(key,fp,result); for(i=0;i<n;i++) { printf("%s\n",result[i]); } printf("検索結果:%d件です。\n",n); fclose(fp); } int search(char key[256],FILE *fp,char *result[256][256]) { int n=0; char *p,word[256],*name; while((p=fgets(word,256,fp))!=NULL) { if(strstr(word,key)!=NULL) { name=strtok(p," "); strcpy(result[n],name); n++; } } return n; } 実行すると、下の警告がでます。 illegal pointer combination(param)
- ベストアンサー
- C・C++・C#
お礼
アドバイスありがとうございました。初めて質問したので質問の仕方がわからなくてお粗末な質問内容になってしまいました。それについてのアドバイスもありがとうございました。明日早速学校でプログラムを修正してみようと思います。