3


3

C:ファイル内の文字列を検索する

私が持っているならば:

const char *mystr = "cheesecakes";
FILE *myfile = fopen("path/to/file.exe","r");

「myfile」に「mystr」が含まれているかどうかを判断する関数を作成する必要があります。 誰かが私を手伝ってくれる? ありがとうございます。

更新:したがって、デプロイする必要のあるプラットフォームには「memstr」がありません。 私のコードで使用できる無料の実装を知っている人はいますか?

6 回答


10


ファイル全体をメモリに収めることができず、GNU `memmem()`拡張機能にアクセスできる場合:

  • できる限りバッファに読み込みます。

  • でバッファを検索する memmem(buffer、len、mystr、strlen(mystr)+ 1);

  • バッファの最後の `strlen(mystr)`文字を除くすべてを破棄し、 それらを最初に移動します。

  • ファイルの終わりに達するまで繰り返します。

memmem`がない場合は、次のように memchr`と `memcmp`を使用してプレーンCで実装できます。

/*
 * The memmem() function finds the start of the first occurrence of the
 * substring 'needle' of length 'nlen' in the memory area 'haystack' of
 * length 'hlen'.
 *
 * The return value is a pointer to the beginning of the sub-string, or
 * NULL if the substring is not found.
 */
void *memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen)
{
    int needle_first;
    const void *p = haystack;
    size_t plen = hlen;

    if (!nlen)
        return NULL;

    needle_first = *(unsigned char *)needle;

    while (plen >= nlen && (p = memchr(p, needle_first, plen - nlen + 1)))
    {
        if (!memcmp(p, needle, nlen))
            return (void *)p;

        p++;
        plen = hlen - (p - haystack);
    }

    return NULL;
}


3


バイナリ配列の文字列を見つけるためのmemmemまたはmemstrがないため(他の人はそれをメモリに読み込んでstrstrを使用することをお勧めします-これは機能しません)、「fgetch」でバイト単位で読み取り、小さな読み取り中に一致する状態マシン。


1


こちらを参照してください。

C99でのボイヤー・ムーアの実装。 これは非常に一般的な文字列検索アルゴリズムであり、O(n)で実行されます。


0


これは、一緒に平手打ちされたバージョンです。 エラーチェックはなく、おそらくオーバーフローバグがあります。 しかし、部分文字列の部分一致に必要なバックトラッキングを説明するために、目的の文字列を見つけたと思います。 15個以上のバグが残っているとは思わない。

編集:最初の回答には少なくとも1つがありました。 真夜中に目が覚め、バックトラッキングチェックが間違っていることに気付きました。 「1212123」で「12123」が見つかりませんでした。 まだ間違っているかもしれませんが、少なくとも今はそれを見つけています。

int main( int argc, char* argv[] )
{
    FILE *fp;
    char *find, *hist;
    int  len, pos=0, hl=0, i;
    char c;

    fp = fopen( argv[1], "r" );
    find = argv[2];
    len = (int)strlen( find );
    hist = malloc( len );
    memset( hist, 0, len );
    while ( !feof( fp )) {
        c = fgetc( fp );
        if ( find[pos++] == c ) {
            if ( pos == len ) {
                printf( "Found it\n" );
                return 1;
            }
        }
        else {
            // check history buffer (kludge for backtracking)
            if ( pos > 0 ) {
                pos = 0;
                for ( i = 0; i < len - 1; i++ )
                    if ( 0 == memcmp( hist+len-i-1, find, i + 1 )) {
                    // we had a mismatch, but the history matches up to len i
                    pos = i;
                }
            }
        }
        // update history buffer - this is innefficient - better as circular buffer
        memmove( hist, hist + 1, len - 1 );
        hist[len-1] = c;
    }
    printf( "Not found\n" );
}


0


バッファ内の文字列を検索する関数を次に示します。

制限:ワイド文字を処理しません(国際化の場合)。 ファイルをメモリに読み込むには、独自のコードを記述する必要があります。 パターンが2つの読み取りバッファーに分割されている場合、パターンは検出されません。

/*****************************************************
const char *buffer    pointer to your read buffer (the larger, the better).
size_t bufsize        the size of your buffer
const char *pattern   pattern you are looking for.

Returns an index into the buffer if pattern is found.
-1 if pattern is not found.

 Sample:
    pos = findPattern (buffer, BUF_SIZE, "cheesecakes");
*****************************************************/

int findPattern (const char *buffer, size_t bufSize, const char *pattern)
{
    int i,j;
    int patternLen;

    // minor optimization. Determine patternLen so we don't
    // bother searching buffer if fewer than patternLen bytes remain.
    patternLen = strlen (pattern);

    for (i=0; i


-1


 chat match = "findthis";
 int depth = 0;
 while(not eof)
 {
     char ch = getonebyte();
     if(ch == match[depth])
     {
         if (depth == strlen(match))
            break;
         else
            depth++;
      }
      else
           depth = 0;
 }

だいたい(そこにいる人たちがいるはずです)