C:在文件中搜索字符串

时间:2010-02-03 00:42:04

标签: c string file search

如果我有:

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

我需要编写一个函数来确定myfile是否包含mystr的任何出现。谁能帮助我?谢谢!

更新:事实证明我需要部署的平台没有memstr。有谁知道我可以在我的代码中使用的免费实现?

6 个答案:

答案 0 :(得分:11)

如果您无法将整个文件放入内存,并且您可以访问GNU memmem()扩展名,那么:

  • 尽可能多地阅读缓冲区;
  • 使用memmem(buffer, len, mystr, strlen(mystr) + 1);
  • 搜索缓冲区
  • 丢弃缓冲区的所有字符,但最后将strlen(mystr)字符移到开头;
  • 重复直到文件结束。

如果您没有memmem,那么您可以使用memchrmemcmp在纯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;
}

答案 1 :(得分:3)

因为没有memmem或memstr来在二进制数组中找到一个字符串(其他建议将其读入内存并使用strstr - 这不起作用)你必须用“fgetch”逐字节读取它写一个小的状态机来匹配它。

答案 2 :(得分:1)

见这里:

http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm

在C99中实施Boyer-Moore。这是一种非常常见的字符串搜索算法,可在O(n)中运行。

答案 3 :(得分:0)

这是一个打耳光的版本。它没有错误检查,可能有溢出错误。但我认为它找到了所需的字符串并说明了部分子串匹配所需的回溯。我怀疑还剩下15个以上的错误。

编辑:第一个答案中至少有一个。我在半夜醒来,发现回溯检查错了。它没有在'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" );
}

答案 4 :(得分:0)

这是一个将在缓冲区中搜索字符串的函数。

限制:它不处理宽字符(在国际化的情况下)。您必须编写自己的代码才能将文件读入内存。如果模式在两个读缓冲区之间分割,则无法找到模式。

/*****************************************************
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<bufSize-patternLen; ++i)
    {
        for (j=0; j<patternLen; ++j)
        {
            if (buffer[i+j] != pattern[j])
            {
                break;
            }
        }
        if (j == patternLen)
        {
            return i;
        }
    }
    return -1;
}

答案 5 :(得分:-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;
 }

粗略地说(我确信那里还有其他人)