2017-02-20 14 views
2

strstr関数を使用して正確な単語を一致させることはできますか?たとえば、のは、私は言葉hello、および入力文字列lineを持っているとしましょう:を使用して正確な単語を一致させる

char* line = "hellodarkness my old friend"; 

場合、私は

result = strstr(line, "hello"); 

result私はしかし、(NULLではないこと)と一致しますを使用正確な単語 "hello"( "hellodarkness"が一致しないように)だけ一致させたい場合、結果はNULLになります。 strstrを使用してこれを行うことはできますか、fscanを使用して、単語ごとに行の単語をスキャンして一致をチェックする必要がありますか?

+3

'はstrstr()は' ...ちょうど真または偽の試合へのポインタ、いないを返し、ちょうどチェックその前と後の文字はアルファベットではない(または好きな場合はアルファベット文字ではない) - そうでない場合、有効なマッチを得ています。そうであれば、返されたポインタの直後からやり直してください。 – Dmitri

+1

['strstr()'](https://linux.die.net/man/3/strstr)のドキュメントはその動作を説明しています。それは、ある文字列の出現を別の文字列の部分文字列として探すことです。そのような部分文字列が見つかった場合、 'strstr()'自体は部分文字列の外観を囲む文字*に関する情報を持ちませんが、あなた自身の周りを見ることができます。 –

答えて

4

私はなります

  • チェック文字列が文
  • にある場合は、開始(lineと同じポインタ)で見つかった場合は、単語の長さを追加し、英数字文字が見つかったかどうかを確認します。そうでない場合(またはヌルで終了)は、その後、他のどこにも見つかった場合
  • にマッチテスト「の前に何alphanum」余分を追加していない

コード:ここ

#include <stdio.h> 
#include <strings.h> 
#include <ctype.h> 
int main() 
{ 
    const char* line = "hellodarkness my old friend"; 
    const char *word_to_find = "hello"; 
    char* p = strstr(line,word_to_find); 
    if ((p==line) || (p!=NULL && !isalnum((unsigned char)p[-1]))) 
    { 
    p += strlen(word_to_find); 
    if (!isalnum((unsigned char)*p)) 
    { 
     printf("Match\n"); 
    } 
    } 
    return 0; 
} 

それは何も印刷されません。前/後に句読点/スペースを挿入するか、"hello"の後に文字列を終了すると、一致します。また、の前にアルファベットの文字を挿入することで一致することはありません。こんにちは。

EDIT:"hello"が1つのみの場合は上記のコードはいいですが、"hello""hellohello hello"に見つけることができません。だから我々はこのように、毎回p進め、単語やNULLを探すためにループを挿入する必要があります。

#include <stdio.h> 
#include <strings.h> 
#include <ctype.h> 
int main() 
{ 
    const char* line = " hellohello hello darkness my old friend"; 
    const char *word_to_find = "hello"; 
    const char* p = line; 

    for(;;) 
    { 
    p = strstr(p,word_to_find); 
    if (p == NULL) break; 

    if ((p==line) || !isalnum((unsigned char)p[-1])) 
    { 
     p += strlen(word_to_find); 
     if (!isalnum((unsigned char)*p)) 
     { 
     printf("Match\n"); 
     break; // found, quit 
     } 
    } 
    // substring was found, but no word match, move by 1 char and retry 
    p+=1; 
    } 

    return 0; 
} 
+0

文字列の先頭でない場合は、一致する前に文字を確認する必要もあります。 – Dmitri

+0

@Dmitri correct。 Cでの文字列操作は決して簡単ではありません... –

+0

@ Jean-FrançoisFabre 'if(p is == line)'を最初にチェックし、 'if(!isalnum(p-1))'、 'strlen(p)'、 'if(!isalnum(p + strlen(word_to_find)))'を実行し、すべての可能性をチェックしました。 – sabbahillel

3

strstr()以来戻りますが確認したい部分文字列の開始位置へのポインタを、あなたはstrlen(result)より長い文字列の部分文字列か、探している分離文字列かをチェックすることができます。 strlen(result) == strlen("hello")の場合、正しく終了します。スペースや句読点(またはその他の区切り文字)で終わると、最後にも区切られます。また、部分文字列の先頭が "長い文字列"の先頭か、空白、句読点、またはその他の区切り文字で始まるかどうかを確認する必要があります。

+0

...しかし、 'strlen()'は次の文字が英数字ではなくてもうまくいっていますので、どのように役立ちますか? – Dmitri

+0

@ドミトリー私は、ポストに区切り文字として必要なチェックリファレンスを追加しました。あまりに速く入力して、次の文を置いておきます。 – sabbahillel

+0

'char * hs =" hello "、* str =" hello world "; 'strlen(x)'は11で 'strlen(hs)'は5だけですが、マッチは有効でなければなりません(全単語マッチ)。 – Dmitri

5

ここには、目的に応じた一般的な機能があります。それは何も見つからない場合は、最初の一致またはNULLへのポインタを返す:あなたが一致するものを見つけた場合

#include <ctype.h> 
#include <string.h> 

char *word_find(const char *str, const char *word) { 
    const char *p = NULL; 
    size_t len = strlen(word); 

    if (len > 0) { 
     for (p = str; (p = strstr(p, word)) != NULL; p++) { 
      if (p == str || !isalnum((unsigned char)p[-1])) { 
       if (!isalnum((unsigned char)p[len])) 
        break; /* we have a match! */ 
       p += len; /* next match is at least len+1 bytes away */ 
      } 
     } 
    } 
    return p; 
} 
関連する問題