- ベストアンサー
簡易grep関数ができません。助けてください><
はじめまして。 C言語初級者の大学生です。 このたび、大学で出た課題で、Perlで製作した簡易grep関数 プログラムを元に、C言語で同様の内容をプログラミングせよ、 という課題が出題されました。 大半はできたのですが、肝心の文字列検索アルゴリズム(特定のワードを含んだ文章の検出)がわかりません。 やり方教えてください、お願いします>< OS:Mac OS X 10.8.5 エディタ:vi Editor 【参考】 Perlで製作した簡易grep関数 #grep for perl version #usage:mygrep pattern file1,file2,... if(@ARGV<1) {die:"Usage mygrep pattern [file.]\n";} $pattern=shift foreach $file (@ARGV) { open(FILE,$file); $line=1; while(<FILE>){ #--------------------------------------------- print "$file $line:$_" if /$pattern/o; #--------------------------------------------- # ↑この部分をC言語で表したいです $line++;} close(FILE); }
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
これって初心者には難しい問題なので回答することにします。 なお、引数の取り方やファイルの読み込み方は定番中の定番ですから覚えておいてください。また、while{} 中の if{} 文節内を改良すれば、様々なパターン検索に拡張できますので、是非トライしてみてください。 /* A simple grep by Mac OSX * file name: gunofkid.c * compile: gcc gunofkid.c * execution: ./a.out 'key word' <file1 <file2 <file...>>> */ #include <stdio.h> #include <string.h> // strstr() #include <stdlib.h> // exit() #define SIZE 256 int main(int argc, char *argv[]) { int line; char *file_name, *key_word, *temp, read_buff[SIZE]; FILE *fp; if (argc<3) { printf("Parameter error.\n"); return 0; } while (argc-- > 2) { /* 任意ファイルを開く */ file_name = argv[argc]; fp = fopen(file_name, "r"); if (fp == NULL) { printf("%s file not found.\n", file_name); exit(1); } /* メイン・プログラム部 */ key_word = argv[1]; line = 0; fgets(read_buff, SIZE, fp); while (!feof(fp)) { line += 1; if (strstr(read_buff, key_word) != NULL) printf("%s %d: %s", file_name, line, read_buff); fgets(read_buff, SIZE, fp); } /* 任意ファイルを閉じる */ fclose(fp); } return 0; }
その他の回答 (3)
- salsberry
- ベストアンサー率69% (495/711)
元のPerl版のプログラムだと、 > perl mygrep.pl while ./*.c このwhileのところに代わりに正規表現を書いて検索することができるので、本当に同等のことができるC言語のプログラムを一から書こうとするとかなりの分量になります。 だから、皆さん「どのくらいの簡易?」と尋ねているわけです。 正規表現でない固定文字列の検索を自力で作成するのであれば、Boyer-Moore法あたりを使うのがいいでしょう。 http://ja.wikipedia.org/w/index.php?title=BM%E6%B3%95
お礼
そういうことでしたか>< 思いっきり勘違いしておりました。 正していただきありがとうございます>< コマンドライン引数を用いた簡単な繰り返し (実行名 繰り返しオプション 数字 文章コピーオプション 文章 で入力し、数字の数だけ繰り返し文章を出力する。オプションの順番は問わない。)ルーチン 構造体メンバ他、C言語入門編の内容を一通り習っている人間が、 プログラミング可能な範囲、ということになります。
- trapezium
- ベストアンサー率62% (276/442)
そうですね。どこまでが簡易かよく分からんところですが、正規表現を実装しろと言ってるわけではなさそうなので、regex ライブラリを使うか、strncmp あたりでお茶を濁すかでしょう。 とりあえず man regex してみてください。
お礼
結局regexライブラリは内容を理解しきれませんでした>< ですが今後の参考になりました。 ご助言ありがとうございましたm(_ _)m
補足
参考ファイルの実行形式は以下の通り perl mygrep.pl while ./*.c 「while」という単語を含む文章をカレントディレクトリ内の.cの拡張子を もつファイルから抜き出し表示するだけ。 ここまで簡易化しております。 regexライブラリはまだ使ってないので、 strncmpくらいでしょうか・・・? man関数使っても「regex_t *preg」の部分がよくわかりません><
- Tacosan
- ベストアンサー率23% (3656/15482)
えぇと, 「簡易」というのはどこまで「簡易」なんでしょうか? fgrep なら簡単だけど, そうじゃないと (ものによっては) やっぱり面倒だよ. ちなみに「特定の文字列を検索する」だけなら, ちょっと調べればすぐにわかると思う. 人間がやるような「自然」な (だけど遅いこともある) アルゴリズムでよければ, 「調べる」までもないかもしれん. 例えば, あなたなら「ある文章から特定の文字列を探す」ときにどのようにしますか?
お礼
ご助言ありがとうございました。m(_ _)m
補足
すいません>< 内容で通じるとばかり・・・ 参考ファイルの実行形式は以下の通り perl mygrep.pl while ./*.c 「while」という単語を含む文章をカレントディレクトリ内の.cの拡張子を もつファイルから抜き出し表示するだけ。 ここまで簡易化しております。 えーと、「特定の文字列を検索する」なら・・・ やはりしらみつぶしに、アルファベットを見比べる・・・くらいでしょうか?
お礼
ありがとうございました。 おかげで、解決できそうです。^^