C:在文件中搜索字符串

如果我有:

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

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

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

如果您无法将整个文件放入内存,并且您可以访问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; } 

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

看这里:

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

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

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

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

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

限制:它不处理宽字符(在国际化的情况下)。 您必须编写自己的代码才能将文件读入内存。 如果模式在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 
  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; } 

大致(我相信那里有一些人)