dポイントプレゼントキャンペーン実施中!

はじめまして。
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);

}

A 回答 (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;
}
    • good
    • 0
この回答へのお礼

ありがとうございました。
おかげで、解決できそうです。^^

お礼日時:2010/01/10 21:47

元のPerl版のプログラムだと、


> perl mygrep.pl while ./*.c
このwhileのところに代わりに正規表現を書いて検索することができるので、本当に同等のことができるC言語のプログラムを一から書こうとするとかなりの分量になります。
だから、皆さん「どのくらいの簡易?」と尋ねているわけです。

正規表現でない固定文字列の検索を自力で作成するのであれば、Boyer-Moore法あたりを使うのがいいでしょう。
http://ja.wikipedia.org/w/index.php?title=BM%E6% …
    • good
    • 0
この回答へのお礼

そういうことでしたか><
思いっきり勘違いしておりました。
正していただきありがとうございます><

コマンドライン引数を用いた簡単な繰り返し
(実行名 繰り返しオプション 数字 文章コピーオプション 文章
で入力し、数字の数だけ繰り返し文章を出力する。オプションの順番は問わない。)ルーチン
構造体メンバ他、C言語入門編の内容を一通り習っている人間が、
プログラミング可能な範囲、ということになります。

お礼日時:2010/01/10 20:48

そうですね。

どこまでが簡易かよく分からんところですが、正規表現を実装しろと言ってるわけではなさそうなので、regex ライブラリを使うか、strncmp あたりでお茶を濁すかでしょう。

とりあえず man regex してみてください。

この回答への補足

参考ファイルの実行形式は以下の通り
perl mygrep.pl while ./*.c
「while」という単語を含む文章をカレントディレクトリ内の.cの拡張子を
もつファイルから抜き出し表示するだけ。
ここまで簡易化しております。

regexライブラリはまだ使ってないので、
strncmpくらいでしょうか・・・?
man関数使っても「regex_t *preg」の部分がよくわかりません><

補足日時:2010/01/10 12:56
    • good
    • 0
この回答へのお礼

結局regexライブラリは内容を理解しきれませんでした><
ですが今後の参考になりました。
ご助言ありがとうございましたm(_ _)m

お礼日時:2010/01/10 21:50

えぇと, 「簡易」というのはどこまで「簡易」なんでしょうか?


fgrep なら簡単だけど, そうじゃないと (ものによっては) やっぱり面倒だよ.
ちなみに「特定の文字列を検索する」だけなら, ちょっと調べればすぐにわかると思う. 人間がやるような「自然」な (だけど遅いこともある) アルゴリズムでよければ, 「調べる」までもないかもしれん. 例えば, あなたなら「ある文章から特定の文字列を探す」ときにどのようにしますか?

この回答への補足

すいません><
内容で通じるとばかり・・・
参考ファイルの実行形式は以下の通り
perl mygrep.pl while ./*.c
「while」という単語を含む文章をカレントディレクトリ内の.cの拡張子を
もつファイルから抜き出し表示するだけ。
ここまで簡易化しております。

えーと、「特定の文字列を検索する」なら・・・
やはりしらみつぶしに、アルファベットを見比べる・・・くらいでしょうか?

補足日時:2010/01/10 12:48
    • good
    • 0
この回答へのお礼

ご助言ありがとうございました。m(_ _)m

お礼日時:2010/01/10 21:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!