2016-10-06 38 views
-2

私はCとポインタを初めて使っているので、今でも地獄です!以下は、単語がテキストファイルに何回出現するかを調べることを主な目的とする関数のコードです。どんな助けもありがとう!C言語のテキストファイルに単語が何回出現するかを調べる

void count_occurrences (int n, FILE *file, Entry *entries) { 
    file = fopen("test/flicka.txt", "r"); 
    if (file != NULL) { 
     char buff[LINE_MAX_CHARS]; 
     int i = 0; 
     char * haystack = fgets(buff, 1000, file); 
     char * needle = NULL; 
     char * p = NULL; 
     while (haystack != NULL) { 
      for (i; i < n; i++) { 
       needle = entries[i].string; 
       while ((p = strstr(haystack, needle)) != NULL) { 
        entries[i].count++; 
        p++; 
       }  
      } 
      haystack = fgets(buff, 1000, file); 
      i = 0; 
     } 
     fclose(file); 
    } 
    else { 
     printf("File not found!\n"); 
    } 
} 
+0

あなたは何度も同じ乾草を探し続けています。すでに検索されている干し草をスキップする必要があります。あなたの 'p ++;'は 'haystack = p + 1;'でなければなりません。これにより、 "aaa"は "aaaaa"と3回一致します。あなたが 'strlen(needle)'をループ外で一度計算できることを除けば、 'haystack = p + strlen(needle);'と一度だけマッチさせたいならば。 –

+0

また、すでに開いている 'FILE *'を関数に渡すか、ローカル変数 'FILE * file'を使用して関数内のファイルを開いたり閉じたりすることにも注意してください。 'FILE * file'を関数に渡さず、ファイルを開くことで無視します。確かに、それは呼び出しコードで 'FILE * 'のコピーを傷つけることはありませんが、無意味です。 (そして、おそらく、ファイルの名前を 'const char * filename'として渡す方が、表示されているようにハードワイヤするよりも良いでしょう。あなた自身のことを繰り返す) –

+0

助けてくれてありがとうジョナサン。どのように引数として与えられたポインタ(FILE *ファイル)を使って関数内のファイルを開くことができますか? – Nick

答えて

0

このような運動の問題点は、特定の問題を解決する最善の方法ということです - ストリームに接続文字ベースのステート・マシンは - より大きな問題にスケールアップしません。

最初に行うには、最初はゼロである「解析位置」を維持します。その後、データがなくなりEOFを得るまでループ内でfgetc()を呼び出します。文字が解析位置にある文字と一致する場合、解析位置をインクリメントします。解析位置が文字列の最後にある場合は一致しているので、カウントをインクリメントします。そうでない場合は、最初の文字が一致するかどうかに応じて解析位置をゼロまたは1にリセットします。

最初の方法は高速で簡単ですが、柔軟性がありません。

より多くの方法は、ラインベースの入力です。行が短くなければならないことを知っているならば大きなバッファを使ってfgetsを呼び出し、行が無制限の場合は "getline"を作ります。次に、行にstrstrを呼び出して、一致するかどうかを確認します。一致する場合は、ポインタを増分して別のポインタを確認する必要があります。

解析可能な方法は、解析とIOを分離し、複数のパターンを検索することを可能にします。擬似コード

while(line = getline()) 
{ 
    N += countwords(line, "myword"); 
} 

int countwords(line, word) 
{ 
    ptr = line; 
    while(strstr(ptr, word)) 
    { 
    ptr = strstr(ptr, word) + strlen(word); // replace strlen with 1 to allow overlaps 
    answer++; 
    } 
} 

が明らかになりましたNs個の配列を維持し、各単語を繰り返し呼び出すと、いくつかの単語を検索するためのメインループを変更する必要があります。しかし、それはどんな種類のパターンマッチングにも適用されます。

関連する問題