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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- JavaScript switch文のswitch(n)の部分を複数の値にするか、if文に変えてほしいです。 1 2022/07/27 17:18
- C言語・C++・C# C++のcase文の書き方 4 2023/02/24 20:50
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ガンマ変換 C言語でプログラ...
-
fopenでファイル名に、変数を使...
-
二分探索木への挿入
-
C言語でファイル読み書きを早く...
-
同時にファイル読み込み 書き込み
-
c言語でのfscanfについて
-
C言語でファイル名を変数にした...
-
C言語でクロマキー合成をする方法
-
C言語でのCSVソートとデータ抽...
-
数値データの読み出しについて
-
初心者のc言語
-
エラーがわかりません、、
-
C言語におけるファイル読み込み...
-
c言語 ファイルから数字を読み...
-
ファイル読み込み EOF 判定
-
成績処理のプログラムについて...
-
ファイルが読み込めない・・・
-
大量の入力ファイルを扱うとき...
-
CRC32の計算方法
-
VisualStudioでのファイルの入...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語でのfscanfについて
-
C言語でファイル読み書きを早く...
-
fopenでファイル名に、変数を使...
-
複数ファイルの同時読み込みの...
-
fgets( ) の返り値は何?
-
テキストファイル内に対して, ...
-
ファイルへの書込み処理が異常...
-
C言語にてXMLファイルから任意...
-
ファイル出力で改行を入れたい!
-
C言語でセグメンテーションエ...
-
エラーがわかりません、、
-
ガンマ変換 C言語でプログラ...
-
VisualStudioでのファイルの入...
-
同時にファイル読み込み 書き込み
-
自己相関関数を求めるプログラ...
-
c言語 ファイルから数字を読み...
-
大量の入力ファイルを扱うとき...
-
ファイルが読み込めない・・・
-
【C言語】ファイルを読み込んで...
-
構造体のメンバにファイルポイ...
おすすめ情報