
DFAを受理するプログラムを組んでいるのですが、コンパイルして動作させるとすぐに終わってしまいます。
どこがいけないのでしょうか…。助言を求めています。
手探りでやっているのですが、ファイル読み込みなど、基本的な所からわかっていない状態です。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
enum { NFA_0_2_3_5, NFA_0_1_2_3_5_6_7_8_10_11_12, NFA_4_7_8_10, NFA_11_12, NFA_9_12, NFA_13_15_16, NFA_14 };
int regex(char *txt, int idx);
int DFA_match(char *txt, int startIndex);
int main (int argc, char *argv[])
{
int c, i, m, idx;
char text[1024], *pattern;
FILE *fp;
pattern = argv[optind++];
for (i = optind; i < argc; i++) {
fp = fopen(argv[i], "r");
if (fp == NULL) {
fprintf(stderr, "File %s: open failed.\n", argv[i]);
} else {
while (fgets(text, sizeof(text), fp) != NULL) {
m = 0;
for (idx = 0; (idx = regex(text, idx)) >= 0; idx++) {
m++;
}
if (m > 0) {
printf("%s: %s", argv[i], text);
}
}
}
}
return 0;
}
int DFA_match(char *txt, int startIndex)
{
int DFAstate = NFA_0_2_3_5;
int acceptLen = -1;
int i;
for (i = startIndex; txt[i] != '\0'; i++) {
switch (DFAstate) {
case NFA_0_2_3_5:
switch(txt[i]){
case 'x':
DFAstate = NFA_0_1_2_3_5_6_7_8_10_11_12;
break;
case 'z':
DFAstate = NFA_4_7_8_10;
break;
default:
return acceptLen;
}
break;
case NFA_0_1_2_3_5_6_7_8_10_11_12:
switch(txt[i]){
case 'x':
DFAstate = NFA_0_1_2_3_5_6_7_8_10_11_12;
break;
case 'z':
DFAstate = NFA_4_7_8_10;
break;
case 'y':
DFAstate = NFA_9_12;
break;
default:
return acceptLen;
}
break;
case NFA_4_7_8_10:
switch(txt[i]){
case 'x':
DFAstate = NFA_11_12;
break;
case 'y':
DFAstate = NFA_9_12;
break;
default:
return acceptLen;
}
break;
case NFA_11_12:
switch(txt[i]){
case 'y':
DFAstate = NFA_9_12;
break;
default:
return acceptLen;
}
break;
case NFA_9_12:
switch(txt[i]){
case 'y':
DFAstate = NFA_13_15_16;
acceptLen = i;
break;
default:
return acceptLen;
}
break;
case NFA_13_15_16:
switch(txt[i]){
case 'x':
DFAstate = NFA_14;
break;
default:
return acceptLen;
}
break;
case NFA_14:
switch(txt[i]){
case 'y':
DFAstate = NFA_13_15_16;
acceptLen = i;
break;
default:
return acceptLen;
}
break;
}
}
return acceptLen;
}
int regex(char *txt, int idx)
{
int i;
for (; idx < strlen(txt); idx++) {
if ( (i = DFA_match(txt, idx)) > 0) {
printf("matched!\n");
return idx;
}
}
return -1;
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
コマンドライン引数がわかってないのかもしれませんね
cygwinで
$ a bbb ccc.txt
とするとa.exeが実行され入力した文字列が引数として渡されます
プログラムで引数をうけとるのが argcとargv[ ] です
argcには引数の数(a, bbb, ccc.txtの3つがあるので3)
argv[ ] にはそれぞれの文字列
argv[0]は"a"
argv[1]は"bbb"
argv[2]は"ccc.txt"
が入ります。
(それとオプション引数を使っている様子はないので<getopt.h>とoptindは要らないのでは。)
回答ありがとうございました。
おっしゃる通り、コマンドライン引数が分かっていない状態で他の文字探索のプログラムを流用して組んだのがmain関数だったので、不要な部分が多くありました。
上の回答を参考にいらない部分を削り、main関数の見直しをしてみたら動作するようになりました。また、今までコマンドライン引数を少し避けてしまっていたのですが、学習するよい機会になりました。
とてもわかりやすい説明をありがとうございました。
No.4
- 回答日時:
>mainで入力すら行えず困っています。
マッチングそのものが正しく動くかどうかは別として、
このプログラムを sample という名前とすると
一行にひとつの対象となる文字列が置かれているようなファイルがあって
sample 適当な文字列 ファイル名1 ファイル名2
とすればプログラム中のDFAを使ってマッチングを試みています。
forも実行していないというのはそういうことではないのですか?
とりあえずは、デバッガーでステップ実行すれば状況が把握できるとお思いますけど。
回答ありがとうございました。
おかげさまでなんとか動作するようになりました。
ファイルの読み込み周辺がまだしっかり理解できていない状態で、他のプログラムを流用してきたのが原因でした。お恥ずかしい限りです。
大変参考になるご意見をありがとうございました。
No.3
- 回答日時:
「DFAを受理する」という言い回しが良くわからない(何かの入力を受理するDFAならわかりますが)のですが、
どこかからもらってきたものですか?
関数 main の先頭付近を見ると
pattern = argv[optind++];
for (i = optind; i < argc; i++) {
fp = fopen(argv[i], "r");
grep のように、プログラムの第一引数にパターン、二番目以降に検索対象のファイルということのようですが、
この pattern は代入されて以降一回も使われていません。
おそらく、本来はこれが正規表現にでもなっていて、そこから
DFAを組み立ててマッチングを行うもののような気がします。
DFA_match は追いかけたくありませんが、受け付けるアルファベットが
x, y, z である文法ということなんでしょうか。
この回答への補足
言葉が足りておらず申し訳ありません。
あらかじめ指定された正規表現(x,y,zで構成される)のパターンがあり、それを受理するDFAから作ったのが関数DFA_matchです。従って受け付けるアルファベットはx,y,zになります。
mainからregexに引数txt(検索対象の文字列)と引数idx(検索開始位置)を渡してマッチングを行いたいのですが、mainで入力すら行えず困っています。
mainは他の文字探索プログラムから適当に流用したものなので、現段階では全く見当違いの内容かもしれません。
ご指摘ありがとうございました。
No.2
- 回答日時:
main で for ループに入っているかどうか, あるいは while でちゃんと読めているかは確認しましたか?
例えば for の直後 (fopen の前) に
printf("argv[%d] = %s\n", i, argv[i]); fflush(stdout);
while の直後 (m = 0 の前) に
printf("text = %s\n", text);
を入れて動かしてみてください.
forループに入ってもいないみたいですね…。
確認もしていませんでした。教えて下さりありがとうございます。
今からもう一度見なおしてテキストの入力方法を調べてみます。
ありがとうございました。
引き続き回答募集しています。
助言などしていただけたら嬉しいです。
No.1
- 回答日時:
はっきりいって長いので読む気なし.
あなたがどのような動作を期待しているのかわからないので,
・どのような動作を期待しているのか
・どのように実行したのか
・どのようなデータを与えたのか
・どのような結果が得られたのか
をきちんと書いてください.
この回答への補足
ご指摘ありがとうございます。焦ったあまりに言葉が足りていませんでした。ごめんなさい。
このプログラムでは、テキストファイルを読み込み・またはテキストを入力して、それをあらかじめ指定されたパターンとマッチさせ、一致していた場合は"matched"と表示させたいと思っています。
関数DFA_matchはそのパターンから作ったDFAに応じてマッチングをする関数です。mainからregexには引数txt(検索対象の文字列)と引数idx(検索開始位置)を渡します。
cygwinでテキスト入力→ctrl+Dでパターンマッチを行うようにしたいのですが、コンパイルはうまく(?)いくのですが動作させると何も入力しないままに終わってしまいます。
以上で大丈夫でしょうか…?
自分ではmainのテキスト入力のあたりがおかしなことになっているのだと思います。しかしどこがまずいのか見直してもわかりません。
引き続きアドバイスを募集しています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルをバイナリフ...
-
fscanfで格納された変数がおか...
-
fscanfでループしてしまう。
-
乱数とファイルの入出力の質問...
-
ファイルが読み込めない・・・
-
fopenでファイル名に、変数を使...
-
C言語でファイル読み書きを早く...
-
fgets( ) の返り値は何?
-
C言語でセグメンテーションエ...
-
画像を読み込み、画素値の度数...
-
csvfファイルの1行目と3行目を...
-
日本語ファイル名のFTPについて
-
popen使用時の実行速度
-
c言語でのfscanfについて
-
複数ファイルの同時読み込みの...
-
ファイル出力で改行を入れたい!
-
「Aに対するBの割合」と「Aに対...
-
Aの値からBの値を除するとは??
-
Enterキーを押されたら次の処理...
-
「指定されたキャストは有効で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
テキストファイル内に対して, ...
-
複数ファイルの同時読み込みの...
-
C言語でファイル読み書きを早く...
-
ファイル出力で改行を入れたい!
-
なぜCSQとCIP形式ではコ...
-
fopenでファイル名に、変数を使...
-
c言語でのfscanfについて
-
C言語にてXMLファイルから任意...
-
_popen() のエラー取得
-
数値のみ抽出(C言語)
-
ランダムアクセスができない
-
C言語でのCSVソートとデータ抽...
-
C言語 連番データの読み込み
-
ファイルの作成・書き込み・読...
-
fscanfでループしてしまう。
-
ファイルへの書込み処理が異常...
-
ファイルを読み込んで条件式を...
-
CSVファイルを読み込み構造体の...
-
C言語でセグメンテーションエ...
-
C言語について
おすすめ情報