- 締切済み
構造体とファイル検索(><)
なかなか前に進めず、困っています。(泣)現在、構造体とファイル検索を考えてるのですが、皆様にアドバイスを頂けたらと思っています。お願い致します。 テキストファイルの内容は自分で適当に作りました。このようにしています。 →ファイル名(soccer.txt)ファイルの中身→ 例「 番号,名前,年齢 」 1 ,川口 能活,33 38,楢崎 正剛,40 20,川島 永嗣,22 10,中澤 佑二,35 51,駒野 友一,19 9 ,中村 俊輔,29 22,遠藤 保仁,17 15,鈴木 啓太,32 19,本田 圭佑,51 28,家長 昭博,25 30,高原 直泰,18 7 ,播戸 竜二,44 ☆ /*記述*/ としているところへどのようにプログラムを書けばよいのかわかりません。(泣)どなたか教えて頂けないでしょうか。お願い致します。 サンプル: // 最大のデータ数 #define MAX_LIST (100) // 関数のプロトタイプ宣言 void read_data( FILE *fp, struct data list[], size_t size ); void print_data( struct data list[], size_t size ); void search_num( struct data list[], size_t size ); void search_name( struct data list[], size_t size ); void search_age( struct data list[], size_t size ); // メイン関数 int main( void ) { struct data list[ MAX_LIST ]; FILE *fp; int menu; if ( (fp = fopen("soccer.txt","r")) != NULL ){ read_data( fp, list, MAX_LIST ); fclose( fp ); do { printf( "条件を選択して下さい[1~4]\n" ); printf( " 1:全部表示\n" ); printf( " 2:番号で検索\n" ); printf( " 3:名前で検索\n" ); printf( " 4:年齢で検索\n" ); printf( "99:終了\n" ); scanf( "%d", &menu ); switch ( menu ){ case 1: print_data( list, MAX_LIST ); break; case 2: search_num( list, MAX_LIST ); break; case 3: search_name( list, MAX_LIST );break; case 4: search_age( list, MAX_LIST ); break; default: break; } } while ( menu != 99 ); return 0; } printf( "soccer.txt - ファイルが見つかりません。\n" ); return 1; } // テキストデータを読み込む専用関数 void read_data( FILE *fp, struct data list[], size_t size ) { /* 記述 */ } // 構造体の内容を表示する専用関数 void print_data( struct data list[], size_t size ) { /* 記述 */ } // 番号で検索 void search_num( struct data list[], size_t size ) { /* 記述 */ } // 名前で検索 void search_name( struct data list[], size_t size ) { /* 記述 */ } // 年齢で検索 void search_age( struct data list[], size_t size ) { /* 記述 */ }
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- splwtr
- ベストアンサー率16% (75/461)
登録件数にもよりますが、 grep で検索した結果をチェックした方が楽そうですね。 そのサンプル・コードだと、機能によってファイルの読み方も違うの? 読んだ内容を識別し、どうチェックするかを、関数ポインタで機能を切り替えて実行すれば、それで済むことじゃないの? 私の場合は、Excelでオート・フィルタ? で対処します。 今使えるものを使った方が楽だから。 csvファイルの先頭に int, string,int とか、型定義な要素があると 使えるかもしれないね。
- aris-wiz
- ベストアンサー率38% (96/252)
どこかで見たコードだと思いましたが、 回答者さんの参考コードそのままですね。。。 >個人情報の掲載や誰かの書いたものをそのまま転記するなどの・・・ #とりあえず禁則事項に触れてる気がしますが。 アドバイスっていうのはあくまでも『助言』であって、 解答をそのまま教えることではありません。 あなたが何を理解していて、何が理解できないのか、 という情報が無ければ、アドバイスのしようも無いと思います。 また、検索の仕様が曖昧です。 例えば、番号は重複することは無い(そういう仕様なら)でしょうが、 年齢や名前というのは、重複する可能性があります。(今回はたまたま無い)そういったものはどうするのでしょうか? ・最初に見つかったものだけ見つかったことにする。 ・全部見つかったことにして個数を数える。 ・そもそも重複を許可しない。 など できれば、あなたがここまでやって、 分からなかったという部分まで説明してください。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス >書けないから投稿しました。すみませんでした。 ↑ 本当かな。前回の質問で search_all() 関数はファイルから行単位で読み込んで処理を 行っていますよ。これを元に読み込み専用の read_data() 関数が作れますけど。 ・あと前回のサンプルの補足ですが、search_num()、search_name()、search_age() 関数の 内部で scanf() 関数を使ってキーボードから検索番号、検索名、検索年齢を入力する部分を 記述して下さい。main() 関数ではメニューの振り分けだけに scanf() でキーボード入力を 行っています。 ・検索番号の search_num() だけ下のサンプルに載せておきますので残りの検索名、検索年齢、 データ読み込み、データ表示は頑張って作成してみて下さい。 サンプル: // 番号で検索 void search_num( struct data list[], size_t size ) { size_t i; int num; // 入力部 printf( "\n検索する番号を入力して下さい:" ); scanf( "%d", &num ); printf( "\n\n" ); // 検索 for ( i = 0 ; i < size ; i++ ){ if ( list[i].no == num ){ /* 番号検索で見つかったときの表示 */ return; } } /* 見つからなかったときのエラー表示 */ } その他: ・上記のサンプルを見れば分かると思いますが、そんなに難しくはありません。 名前の検索、年齢の検索は上記のを参考にすれば直ぐにできると思います。 頑張って作成してみて下さい。 ・あと print_data() 関数は上記のサンプルで入力部をなくして構造体のデータを 順番に printf() していけば出来ます。前回の質問であった search_all() に >printf("%s %s %s \n", lis->no, lis->name, lis->age); ↑ この1行がありますよね。 上記のサンプルの『検索』の for ループに printf() の1行を記述すれば print_data() 関数は出来ますよ。 ・以上。
- maku_x
- ベストアンサー率44% (164/371)
とりあえず一部コードを書いてみます。C言語を書くのは久しぶりなので、間違っていても責めないでください(笑)。 #define MAXBUF 256 #define DELIMITER "," // テキストデータを読み込む専用関数 int read_data( FILE *fp, struct data list[], size_t size ) { char buf[MAXBUF], *s_st, *s_nxt; int cnt=0; while (fgets(buf, MAXBUF, fp) != NULL) { s_st = buf; s_nxt = strtok(buf, DELIMITER); if (s_nxt != NULL) { /* 選手の番号 */ *s_nxt = '\0'; list[cnt].no = atoi(s_st); s_st = s_nxt + 1; } s_nxt = strtok(NULL, DELIMITER); if (s_nxt != NULL) { /* 選手の名前 */ *s_nxt = '\0'; strcpy(list[cnt].name, s_st); s_st = s_nxt + 1; } s_nxt = strtok(NULL, DELIMITER); /* 選手の年齢 */ if (s_nxt != NULL) { *s_nxt = '\0'; } list[cnt].age = atoi(s_st); if (++cnt >= size) { break; } } list[cnt].no = (-1); /* データの終わり */ return cnt; } // 全ての構造体の内容を表示する専用関数 int print_all_data( struct data list[], size_t size ) { int cnt; for (cnt=0; (cnt<size) && (list[cnt].no >= 0); cnt++) { /* 1つの構造体の内容を表示 */ print_data(&list[cnt]); } return cnt; } // 番号で検索 int search_num( struct data list[], int search_num, size_t size ) { int cnt, scnt=0, snum_min, snum_max; switch (search_num) { /* 検索条件の振り分け */ case 1: snum_min = 1; snum_max = 9; break; case 2: snum_min = 10; snum_max = 19; break; case 3: snum_min = 20; snum_max = 29; break; case 4: snum_min = 30; snum_max = 0x7fffffff; break; default: snum_min = (-1); snum_max = (-1); break; } for (cnt=0; (cnt<size) && (list[cnt].no >= 0); cnt++) { if ((list[cnt].no >= snum_min) && (list[cnt].no <= snum_max) ) { /* 条件に合う構造体の内容を表示 */ print_data(&list[cnt]); scnt++; } } return scnt; } こんなところでしょうか。 print_data() は1つの構造体を出力するだけですから、書けますよね。 search_name() や search_age() は、上記 search_num() を基に、適宜書き換えれば良いはずです。 また、main() の中の search_~() を呼ぶ前に、条件を入力する処理を追加してください。 分からない関数があったら、linuxの man ~ とか、参考URLで調べてください。
- 参考URL:
- http://www.linux.or.jp/JM/
- koko_u_
- ベストアンサー率18% (459/2509)
http://okwave.jp/qa3114524.html の続き。というかまるで進んでませんな。 ちょっとは自分で書こうよ。
- rabbit_cat
- ベストアンサー率40% (829/2062)
で、その構造体の定義は?
補足
書けないから投稿しました。すみませんでした。